/*
*
*  $Id: dialogoadquisicion.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
*
*
*/
//#define _GINKGO_TRACE
#if defined(_WINDOWS)
	#if !defined (_SCL_SECURE_NO_WARNINGS)
		#define _SCL_SECURE_NO_WARNINGS
	#endif
	#if !defined (_CRT_SECURE_NO_WARNINGS)
		#define _CRT_SECURE_NO_WARNINGS
	#endif
#else
	#if defined(__DEPRECATED)
		#undef __DEPRECATED
	#endif
#endif

#include <api/globals.h>
#include <api/ilock.h>
#include <set>

#include <wx/wx.h>
#include <wx/animate.h>
#include <wx/imaglist.h>
#include <wx/dnd.h>
#include <wx/tokenzr.h>
#include <main/controllers/configurationcontroller.h>
#include <wx/ginkgostyle/ginkgostyle.h>
#include <wx/propiedades/wxpropiedades.h>

#include "dialogoadquisicion.h"
#include "downloadelementcontainerpanel.h"

#include <resources/ginkgoresourcesmanager.h>
#include <main/entorno.h>
#include <main/controllers/controladorcomandos.h>
#include <main/controllers/controladorpermisos.h>
#include <main/controllers/controladorlog.h>
#include <main/controllers/controladoreventos.h>
#include <main/controllers/historytoolscontroller.h>
#include <eventos/progresocomando.h>

#define SIZE_ICONOS 16

#define ICONO_ESTUDIO 0
#define ICONO_SERIE 1
#define ICONO_HOMBRE 2
#define ICONO_MUJER 3
#define ICONO_OTRO 4
#define SIZE_ICONOS 16

//////////////////////////////////////////////////////////////////////////

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

GNC::GUI::DialogoAdquisicion* GNC::GUI::DialogoAdquisicion::Instance()
{
	if (m_pInstance == NULL) {
		m_pInstance = new DialogoAdquisicion(GNC::HistoryToolsController::Instance()->GetHistoryPanel()->GetWxWindow());
	}
	return m_pInstance;
}

void GNC::GUI::DialogoAdquisicion::FreeInstance()
{
	if(m_pInstance!=NULL){
		m_pInstance->Close();
		m_pInstance = NULL;
	}
}

GNC::GUI::DialogoAdquisicion* GNC::GUI::DialogoAdquisicion::m_pInstance = NULL;


GNC::GUI::DialogoAdquisicion::DialogoAdquisicion(wxWindow* pParent) : DialogoAdquisicionBase(pParent)
{
	m_pResultado = NULL;
	m_pDescargasGridTable = NULL;
	m_SizeRestriction = false;
	m_SizeOK = false;
	m_reverseOrder = true;
	m_pComandoPACS = NULL;
	m_pImageList = new wxImageList(SIZE_ICONOS,SIZE_ICONOS,true);
	m_Mode = TD_SERIES;

	//animation
	m_pAnimation = new wxAnimationCtrl(m_pPanelPACS,wxID_ANY,GinkgoResourcesManager::ProgressBar::GetAniLoading());
	m_pAnimation->Hide();
	m_pSizerAnimation->Add(m_pAnimation, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

	m_AutoAddSeries = false;
	m_AutoAddSeriesItem = NULL;

	m_pImageList->Add(GinkgoResourcesManager::History::GetIcoEstudio());
	m_pImageList->Add(GinkgoResourcesManager::History::GetIcoSerie());
	m_pImageList->Add(GinkgoResourcesManager::History::GetIcoHombre());
	m_pImageList->Add(GinkgoResourcesManager::History::GetIcoMujer());
	m_pImageList->Add(GinkgoResourcesManager::History::GetIcoOtro());
	m_pTreeListResultados->SetImageList(m_pImageList);

	m_pTreeListResultados->SetMainColumn(0);
	m_pTreeListResultados->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( DialogoAdquisicion::OnTreeSelChanged ), NULL, this);
	m_pTreeListResultados->Connect(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( DialogoAdquisicion::OnTreeItemActivated ), NULL, this);
	m_pTreeListResultados->Connect(wxEVT_COMMAND_TREE_ITEM_MENU, wxTreeEventHandler( DialogoAdquisicion::OnTreeItemMenu ), NULL, this);
	m_pTreeListResultados->Connect(wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxTreeEventHandler( DialogoAdquisicion::OnTreeItemExpanded ), NULL, this);
	m_pTreeListResultados->Connect(wxEVT_COMMAND_TREE_BEGIN_DRAG, wxTreeEventHandler( DialogoAdquisicion::OnTreeBeginDrag ), NULL, this);
	m_pTreeListResultados->Connect(wxEVT_COMMAND_LIST_COL_CLICK, wxListEventHandler( DialogoAdquisicion::OnClickColumnHeader), NULL, this);

	m_pDownloadPanel = new DownloadElementContainerPanel(m_pZonaDescargas);
	m_pZonaDescargas->GetSizer()->Add(m_pDownloadPanel, 1, wxEXPAND|wxALL, 5);
	m_pZonaDescargas->Layout();

	if(GNC::GCS::IControladorPermisos::Instance()->Get("core.pacs.limits", "patient_scope")) {
		int tmpIndex = m_pFieldCombo->FindString(_("Id"));
		if (tmpIndex > 0) {
			m_pFieldCombo->Remove(tmpIndex,tmpIndex);
		}
		tmpIndex = m_pFieldCombo->FindString(_("Name"));
		if (tmpIndex > 0) {
			m_pFieldCombo->Remove(tmpIndex,tmpIndex);
		}
		m_pTextControlField->SetEditable(false);
		m_pTextControlField->Enable(false);
		m_pFieldCombo->Enable(false);
		m_pPACSListaServidores->Enable(false);

		m_pTextControlField->Show(false);
		m_pFieldCombo->Show(false);
		m_pPatientLabelStr->Show(false);
		m_pLabelRestricted->Show(true);
		m_pPanelPACS->Layout();
	}
	else {
		int tmpIndex = m_pFieldCombo->FindString(_("Name"));
		if (tmpIndex < 0) {
			m_pFieldCombo->Insert(_("Name"),0);
		}
		tmpIndex = m_pFieldCombo->FindString(_("Id"));
		if (tmpIndex < 0) {
			m_pFieldCombo->Insert(_("Id"),0);
		}
	}
	m_pFieldCombo->Select(0);

	//modalities
	{
		const int MaxModalityNumber=20; // Modificar la constante si se añaden o quitan códigos de modalidad
		std::string modalidades[MaxModalityNumber] = {"CR","CT","DR","DX","IO","MG","MR","NM","OT","PT","RF","RG","SC","OCT","US","XA","XC","ES","ECG","HD"};
		for(int i = 0; i<MaxModalityNumber; i++) {
			wxCheckBox* pCheckBox = new wxCheckBox( m_pPanelPACS, wxID_ANY, wxString::FromUTF8(modalidades[i].c_str()), wxDefaultPosition, wxDefaultSize, 0 );
			m_pModalitySizer->Add( pCheckBox, 0, wxALL, 2 );
			m_modalitiesList.push_back(pCheckBox);
			pCheckBox->Connect( wxEVT_KEY_UP, wxKeyEventHandler( DialogoAdquisicion::OnKeyDownFormulario ), NULL, this );
		}
		m_pPanelPACS->Layout();
		m_pPanelSearch->Layout();
		m_notebook1->Layout();
	}

	m_pModeloDicom = GNC::GCS::Ptr<IModeloDicom>(new IModeloDicom());

	Layout();
	GNC::GCS::ControladorEventos::Instance()->Registrar(this, GNC::GCS::Events::EventoProgresoComando());
}

GNC::GUI::DialogoAdquisicion::~DialogoAdquisicion()
{
	GNC::Entorno::Instance()->GetControladorComandos()->AbortarComandosDeOwner(this);
	{
		this->m_pTreeListResultados->DeleteRoot();
	}
	delete m_pImageList;
	m_pAnimation->Destroy();
}

bool GNC::GUI::DialogoAdquisicion::Show(const std::string& idPatient, const std::string& idPACS)
{
	CenterOnParent();
	m_pTextControlField->Show(true);
	m_pFieldCombo->Show(true);
	m_pPatientLabelStr->Show(true);
	m_pLabelRestricted->Show(false);

	m_pTextControlField->Enable(true);
	m_pTextControlField->SetValue(wxString::FromUTF8(idPatient.c_str()));

	m_pPanelPACS->Layout();

	GNC::GCS::ConfigurationController::Instance()->writeStringUser("/GinkgoCore/Adquisicion", "PACSDefecto", idPACS);

	//load pacs list and select pacs..
	bool retVal = Show(true);

	Search();

	return retVal;
}

bool GNC::GUI::DialogoAdquisicion::Show(bool show)
{
	//se recarga la lista de servidores pacs
	wxArrayString serverListString;
	std::string pacsDef;
	GNC::GCS::ConfigurationController::Instance()->readStringUser("/GinkgoCore/Adquisicion", "PACSDefecto", pacsDef);
	int defaultIndex = 0;
	int ind = 0;
	for (DicomServerHolder* sl = DicomServerList::Instance()->GetList(); sl != NULL; sl = sl->next, ++ind) {
		std::ostringstream ostr;
		ostr << sl->server.ID << " (" << sl->server.AET << "@" << sl->server.HostName << ":" << sl->server.Port << ")";
		serverListString.push_back(wxString::FromUTF8(ostr.str().c_str()));
		if (sl->server.ID == pacsDef) {
			defaultIndex = ind;
			m_Mode = sl->server.retrieveSeries?TD_SERIES:TD_STUDIES;
		}
	}
	m_pPACSListaServidores->Clear();
	m_pPACSListaServidores->Append(serverListString);


	if(m_pPACSListaServidores->GetCount()>0){
		//se selecciona el pacs por defecto
		m_pPACSListaServidores->SetSelection(defaultIndex);
	} else {
		m_pPACSListaServidores->AppendString(_("There is no any PACS configured"));
		m_pPACSListaServidores->SetSelection(0);
		m_pPACSListaServidores->Disable();
	}

	if (IsShown())
	{		
		Raise();
	}
	return DialogoAdquisicionBase::Show(show);
}



//---------------------------------------------------------------------------
//region Eventos de interfaz
void GNC::GUI::DialogoAdquisicion::OnPACSChanged(wxCommandEvent & )
{
	int selected = m_pPACSListaServidores->GetCurrentSelection();
	DicomServerHolder* sl = DicomServerList::Instance()->GetList();
	for (int ind = 0; sl != NULL && ind < selected; sl = sl->next, ++ind);

	if (sl == NULL) {
		return;
	}

	GNC::GCS::ConfigurationController::Instance()->writeStringUser("/GinkgoCore/Adquisicion","PACSDefecto", sl->server.ID);

	if(m_pComandoPACS != NULL)
	{
		GNC::Entorno::Instance()->GetControladorComandos()->AbortarComando(m_pComandoPACS, false);
	}
	m_pModeloDicom = GNC::GCS::Ptr<IModeloDicom>(new IModeloDicom());
	{
		//GNC::GCS::ILocker locker(m_TreeListResultadosLocker);
		this->m_pTreeListResultados->DeleteRoot();
		m_AutoAddSeries = false;
		m_Mode = sl->server.retrieveSeries?TD_SERIES:TD_STUDIES;
	}
}

void GNC::GUI::DialogoAdquisicion::OnKeyDownFormulario( wxKeyEvent& event )
{
	if(event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER) {
		wxCommandEvent evt;
		if (m_pTextControlField->IsEnabled()) {
			OnBusquedaClick(evt);
		}
		event.Skip(false);
	}
	else {
		if(event.GetKeyCode() == WXK_ESCAPE) {
			this->Hide();
			event.Skip(false);
		}
	}
	event.Skip(true);
}


void GNC::GUI::DialogoAdquisicion::OnFechaDesdeDateChanged( wxDateEvent& /*event*/ )
{
	m_pBetween->SetValue(true);
}



void GNC::GUI::DialogoAdquisicion::OnFechaHastaDateChanged( wxDateEvent& /*event*/ )
{
	m_pBetween->SetValue(true);
}

void GNC::GUI::DialogoAdquisicion::OnCancelClick( wxCommandEvent&  )
{
	if (m_AutoAddSeries)  {
		m_AutoAddSeries = false;
		m_AutoAddSeriesItem = NULL;
	}

	if(m_pComandoPACS != NULL)
	{
		m_pTextControlField->ShowCancelButton(false);
		ShowAnimation(false);
		GNC::Entorno::Instance()->GetControladorComandos()->AbortarComando(m_pComandoPACS, false);
		m_pComandoPACS = NULL;

		//GNC::GCS::ILocker locker(m_TreeListResultadosLocker);
		if(m_lastExpanded.IsOk()) {
			m_pTreeListResultados->Collapse(m_lastExpanded);
		} else {
			LimpiarBusquedas(false);
		}
	}
}

void GNC::GUI::DialogoAdquisicion::OnBusquedaClick( wxCommandEvent&  )
{
	Search();
}

void GNC::GUI::DialogoAdquisicion::Search()
{
	if (m_AutoAddSeries)  {
		m_AutoAddSeries = false;
		m_AutoAddSeriesItem = NULL;
	}

	if(m_pComandoPACS != NULL)
	{
		m_pTextControlField->ShowCancelButton(false);
		ShowAnimation(false);
		GNC::Entorno::Instance()->GetControladorComandos()->AbortarComando(m_pComandoPACS, false);
		m_pComandoPACS = NULL;

		//GNC::GCS::ILocker locker(m_TreeListResultadosLocker);
		if(m_lastExpanded.IsOk()) {
			m_pTreeListResultados->Collapse(m_lastExpanded);
		} else {
			LimpiarBusquedas(false);
		}
	}

	std::string server = GetServerSeleccionado();
	m_pModeloDicom = GNC::GCS::Ptr<IModeloDicom>(new IModeloDicom());
	if(server=="")
		return;

	std::string fechaDesde("");
	std::string fechaHasta("");
	std::string timeFrom("");
	std::string timeTo("");
	if (m_pBetween->GetValue()){
		if(m_pTextControlFechaDesde->GetValue().IsValid()){
			fechaDesde =  std::string(m_pTextControlFechaDesde->GetValue().Format(wxT("%Y%m%d")).ToUTF8());
		}
		if(m_pTextControlFechaHasta->GetValue().IsValid()){
			fechaHasta =  std::string(m_pTextControlFechaHasta->GetValue().Format(wxT("%Y%m%d")).ToUTF8());
		}
	} else if (m_pToday->GetValue() || m_pTodayAM->GetValue() || m_pTodayPM->GetValue()) {
		fechaDesde = fechaHasta = wxDateTime::Now().Format(wxT("%Y%m%d")).ToUTF8();
		if (m_pTodayAM->GetValue()) {
			timeFrom = "000000";
			timeTo = "115959";
		} else if (m_pTodayPM->GetValue()) {
			timeFrom = "120000";
			timeTo = "235959";
		}
	} else if (m_pYesterday->GetValue()) {
		fechaDesde = wxDateTime::Now().Add(wxDateSpan(0,0,0,-1)).Format(wxT("%Y%m%d")).ToUTF8();
	} else if (m_pLastWeek->GetValue()) {
		fechaDesde = wxDateTime::Now().Add(wxDateSpan(0,0,-1,0)).Format(wxT("%Y%m%d")).ToUTF8();
	} else if (m_pLastMonth->GetValue()) {
		fechaDesde = wxDateTime::Now().Add(wxDateSpan(0,-1,0,0)).Format(wxT("%Y%m%d")).ToUTF8();
	} else if (m_pLastThreeMonths->GetValue()) {
		fechaDesde = wxDateTime::Now().Add(wxDateSpan(0,-3,0,0)).Format(wxT("%Y%m%d")).ToUTF8();
	}

	if(fechaDesde == "" && fechaHasta == "" && m_pTextControlField->GetValue().size() == 0)
	{
		int answer = wxMessageBox(_("Search without parameters could take al long time\nWould you like to continue?"),_("Search"), wxYES_NO , this);
		if (answer == wxNO) {
			return;
		}
	}

	std::string idPaciente, nombrePaciente, studyUID, accNumber;

	if (m_pFieldCombo->GetValue() == _("Id")) {
		idPaciente = m_pTextControlField->GetValue().ToUTF8();
	} else if (m_pFieldCombo->GetValue() == _("Name")) {
		nombrePaciente = m_pTextControlField->GetValue().ToUTF8();
	} else if (m_pFieldCombo->GetValue() == _("Acc#")) {
		accNumber = m_pTextControlField->GetValue().ToUTF8();
	} else if (m_pFieldCombo->GetValue() == _("Study UID")) {
		studyUID = m_pTextControlField->GetValue().ToUTF8();
	}


	//modalities checked


	GADAPI::ComandoPACSParams * pParams = new GADAPI::ComandoPACSParams(
		idPaciente,
		nombrePaciente,
		studyUID,
		accNumber,
		GetModalities(),
		fechaDesde,fechaHasta,
		timeFrom, timeTo,
		server, GADAPI::ComandoPACSParams::TA_Estudio, m_pModeloDicom, this); // Buscamos los estudios del paciente

	m_pComandoPACS = new GADAPI::ComandoPACS(pParams);
	GNC::Entorno::Instance()->GetControladorComandos()->ProcessAsync(_Std("Exploring PACS..."),m_pComandoPACS, this);
	m_pTextControlField->ShowCancelButton(true);
	ShowAnimation(true);
}

std::string GNC::GUI::DialogoAdquisicion::GetModalities()
{
	std::string modalities;
	bool all = true;

	for (TModalitiesVector::iterator it =m_modalitiesList.begin(); it !=m_modalitiesList.end(); ++it) {
		wxCheckBox* pCheck = dynamic_cast<wxCheckBox*>(*it);
		if(pCheck != NULL)
			if(pCheck->IsChecked()){
				all = false;
				if (modalities == ""){
					modalities = pCheck->GetLabel().ToUTF8();
				}
				else{
					modalities.append("\\");
					modalities.append(pCheck->GetLabel().ToUTF8());
				}
			}
	}
	if (all) {
		modalities = "*";
	}
	return modalities;
}

void GNC::GUI::DialogoAdquisicion::OnLimpiarClick( wxCommandEvent& /*event*/ )
{
	LimpiarBusquedas();
}

void GNC::GUI::DialogoAdquisicion::OnCloseClick( wxCommandEvent& /*event*/ )
{
	Hide();
}

void GNC::GUI::DialogoAdquisicion::OnDescargarClick( wxCommandEvent& /*event*/ )
{
	AddDescarga(true);
}

// Eventos del Treelist
void GNC::GUI::DialogoAdquisicion::OnTreeSelChanged(wxTreeEvent& event)
{

	wxTreeItemId item = event.GetItem();
	if(item.IsOk()){
		wxTreeItemId idPadre = m_pTreeListResultados->GetItemParent(item);
		m_pBDescargar->Enable(idPadre != m_pTreeListResultados->GetRootItem()); // El item es un estudio o una serie
	} else {
		m_pBDescargar->Enable(false);
	}

	event.Skip(true);

}

void GNC::GUI::DialogoAdquisicion::OnTreeItemActivated(wxTreeEvent& event)
{

	AddDescarga(false);

	event.Skip(true);

}

void GNC::GUI::DialogoAdquisicion::OnTreeItemMenu(wxTreeEvent& event)
{
	//clase menu contextual
	class PopUpMenuDescargar: public wxMenu
	{
	public:
		PopUpMenuDescargar(DialogoAdquisicion* pDlg, bool allowDownload, bool series = false) : wxMenu()
		{
			m_pDlg = pDlg;
			if (allowDownload) {
				wxString label;
				if(series) {
					label = _("Download series");
				} else {
					label = _("Download study");
				}

				wxMenuItem* descargar = new wxMenuItem( this,wxID_ANY,label);
#ifdef __WXMSW__
				descargar->SetBitmaps(GinkgoResourcesManager::Acquisition::GetIcoDownload());
#else
				descargar->SetBitmap(GinkgoResourcesManager::Acquisition::GetIcoDownload());
#endif
				Append(descargar);
				this->AppendSeparator();

				Connect(descargar->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( PopUpMenuDescargar::OnDescargar ), NULL, this);
			}
			wxMenuItem* props = new wxMenuItem( this, wxID_ANY, _("Properties..."));
			Append(props);
			Connect(props->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( PopUpMenuDescargar::OnProperties ),NULL, this);

		}
		~PopUpMenuDescargar()
		{
			m_pDlg = NULL;
			Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( PopUpMenuDescargar::OnDescargar ), NULL, this);
			Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( PopUpMenuDescargar::OnProperties ), NULL, this);
		}

		void OnDescargar(wxCommandEvent& )
		{
			if (m_pDlg) {
				m_pDlg->AddDescarga(true);
			}
		}

		void OnProperties(wxCommandEvent& )
		{
			if (m_pDlg) {
				m_pDlg->ShowProperties();
			}
		}

		DialogoAdquisicion* m_pDlg;

	};
	//
	wxTreeItemId item = event.GetItem();
	if(item.IsOk()){
		wxTreeItemId idPadre = m_pTreeListResultados->GetItemParent(item);
		if(idPadre != m_pTreeListResultados->GetRootItem() ){ // El item es un estudio o una serie
			wxTreeItemId idAbuelo = m_pTreeListResultados->GetItemParent(m_pTreeListResultados->GetItemParent(item));
			// Comprobamos que el item es un estudio o es una serie desplegada.
			if ( idAbuelo == m_pTreeListResultados->GetRootItem() ) {
				PopUpMenuDescargar* pMenu = new PopUpMenuDescargar(this, true,false);
				m_pTreeListResultados->PopupMenu(pMenu);
				delete pMenu;
			} else if ( !(m_pTreeListResultados->GetItemText(item, COLUMNA_UID)).empty() ) {
				PopUpMenuDescargar* pMenu = new PopUpMenuDescargar(this, true,true);
				m_pTreeListResultados->PopupMenu(pMenu);
				delete pMenu;
			}
		}
		else {
			PopUpMenuDescargar* pMenu = new PopUpMenuDescargar(this, false);

			m_pTreeListResultados->PopupMenu(pMenu);

			delete pMenu;
		}
	}
}

void GNC::GUI::DialogoAdquisicion::OnTreeItemExpanded(wxTreeEvent& event)
{
	{
		//GNC::GCS::ILocker locker(m_TreeListResultadosLocker);
		wxTreeItemId item = event.GetItem();

		if (m_AutoAddSeries && (m_AutoAddSeriesItem != item) )  {
			m_AutoAddSeries = false;
			m_AutoAddSeriesItem = NULL;
		}

		if(item && item.IsOk()){
			m_pTreeListResultados->SortChildren(item);
			//si el abuelo del item es root => consultar
			if(m_pTreeListResultados->IsExpanded(item) && m_pTreeListResultados->GetItemParent(m_pTreeListResultados->GetItemParent(item)) == m_pTreeListResultados->GetRootItem())
			{
				//se cancela el anterior comando y se contrae el item expandido
				if(m_pComandoPACS != NULL)
				{
					GNC::Entorno::Instance()->GetControladorComandos()->AbortarComando(m_pComandoPACS, false);
					m_pComandoPACS = NULL;
					if(m_lastExpanded.IsOk()) {
						m_pTreeListResultados->Collapse(m_lastExpanded);
					}
				}

				std::string server=GetServerSeleccionado();
				if(server=="")
					return;

				GADAPI::ComandoPACSParams * pParams = new GADAPI::ComandoPACSParams(
					"",
					"",
					std::string(m_pTreeListResultados->GetItemText(item,COLUMNA_UID).ToUTF8()),
					"",
					GetModalities(),
					"",
					"",
					"",
					"",server, GADAPI::ComandoPACSParams::TA_Serie, m_pModeloDicom, this);

				m_pComandoPACS = new GADAPI::ComandoPACS(pParams);
				GNC::Entorno::Instance()->GetControladorComandos()->ProcessAsync(_Std("Exploring PACS..."),m_pComandoPACS, this);
				m_pTextControlField->ShowCancelButton(true);
				ShowAnimation(true);
				m_lastExpanded = item;
			}
			event.Skip(false);
		} else {
			event.Skip(true);
		}
	}

}

void GNC::GUI::DialogoAdquisicion::OnTreeBeginDrag(wxTreeEvent& )
{
	wxTreeItemId seleccion = m_pTreeListResultados->GetSelection();
	if(seleccion.IsOk()){
		if(m_pTreeListResultados->GetItemParent(seleccion) == m_pTreeListResultados->GetRootItem()){
			//esto es para que de la impresion de que no podemos arrastrar la raiz
			class wxFooDataObject: public wxDataObjectSimple
			{
			public:
				wxFooDataObject():wxDataObjectSimple() {}
				~wxFooDataObject() {}
			};
			wxFooDataObject myData;
			wxDropSource dragSource(myData,this);
			dragSource.DoDragDrop(wxDrag_AllowMove);
		}else {
			//comenzamos drag & drop
			wxTextDataObject myData(wxT(""));
			wxDropSource dragSource(myData,this);
			wxDragResult result = dragSource.DoDragDrop(wxDrag_AllowMove);
			if (result == wxDragCopy) {
				AddDescarga(true);
			}
		}
	}
}

void GNC::GUI::DialogoAdquisicion::OnClickColumnHeader(wxListEvent& event)
{
	int column = event.GetColumn();
	m_reverseOrder = !m_reverseOrder;
	m_pTreeListResultados->SortChildren(m_pTreeListResultados->GetRootItem(), column, m_reverseOrder);
}

std::string GNC::GUI::DialogoAdquisicion::GetServerSeleccionado()
{
	std::string id;

	int selected = m_pPACSListaServidores->GetCurrentSelection();
	DicomServerHolder* sl = DicomServerList::Instance()->GetList();
	for (int ind = 0; sl != NULL && ind < selected; sl = sl->next, ++ind);

	if (sl != NULL) {
		id = sl->server.ID;
	} else {
		wxMessageBox(_("Select a valid PACS Server"), _("Info"),
			wxOK | wxICON_INFORMATION, this);
	}

	return id;
}


// Obtiene el item seleccionado del TreeList de resultados, genera una descarga, la apila y la inicia.
void GNC::GUI::DialogoAdquisicion::AddDescarga(bool lanzarBusqueda)
{
	{
		//GNC::GCS::ILocker locker(m_TreeListResultadosLocker);
		wxTreeItemId seleccion = m_pTreeListResultados->GetSelection();

		if(seleccion.IsOk()){
			if(m_pTreeListResultados->GetItemParent(seleccion) == m_pTreeListResultados->GetRootItem()){
				return;
			} //raiz
			else if(m_pTreeListResultados->GetItemParent(m_pTreeListResultados->GetItemParent(seleccion)) == m_pTreeListResultados->GetRootItem()){
				//studies
				if (m_Mode == TD_STUDIES) {
					//download study node
					//std::string uidPaciente = std::string(m_pTreeListResultados->GetItemText(m_pTreeListResultados->GetItemParent(seleccion), COLUMNA_UID).ToUTF8());
					std::string descPaciente = std::string(m_pTreeListResultados->GetItemText(m_pTreeListResultados->GetItemParent(seleccion)).ToUTF8());

					std::string uidStudy = std::string(m_pTreeListResultados->GetItemText(seleccion, COLUMNA_UID).ToUTF8());
					std::string descStudy = std::string( (m_pTreeListResultados->GetItemText(seleccion) + _T("(") + m_pTreeListResultados->GetItemText(seleccion, COLUMNA_MODALIDAD) + _T(")") ).ToUTF8());
					std::string modStudy =  std::string( m_pTreeListResultados->GetItemText(seleccion, COLUMNA_MODALIDAD ).ToUTF8());

					if (!IsAllowedToDownload(modStudy)) {
						LOG_ERROR("GUI/Adquisition", _Std("Download of modality ") << modStudy << _Std(" not allowed"));
						wxMessageBox(_("You are not allowed to download this kind of modalities."),_("Modality download error"),wxICON_ERROR);
					} else {
						bool forceInit = true;
						if (m_pDownloadPanel->FindDownload(uidStudy)) {
							forceInit = wxMessageBox(_("Studies are already in the download queue.\nDo you want to repeat download?"),_("Download warning"),wxICON_INFORMATION|wxYES_NO) == wxYES;
						}

						bool downloaded = m_pDownloadPanel->AddDownload(GetServerSeleccionado(), descPaciente, descStudy,modStudy, forceInit, false, uidStudy, "");
						m_pTreeListResultados->SetItemBold(seleccion, downloaded);
					}

				} else { 
					//series mode, we have to search series in study
					if (lanzarBusqueda) {

						//estamos en un estudio
						//std::string uidPaciente = std::string(m_pTreeListResultados->GetItemText(m_pTreeListResultados->GetItemParent(seleccion), COLUMNA_UID).ToUTF8());
						std::string descPaciente = std::string(m_pTreeListResultados->GetItemText(m_pTreeListResultados->GetItemParent(seleccion)).ToUTF8());
						std::string uidStudy = std::string(m_pTreeListResultados->GetItemText(seleccion, COLUMNA_UID).ToUTF8());

						// Necesitamos buscar las series

						// Primero comprobamos que no estan ya desplegadas, y asi ahorramos una busqueda en el PACS.
						wxTreeItemId eid = seleccion;
						std::string server = GetServerSeleccionado();
						int numSeriesDescargadas = 0;

						std::list<wxTreeItemId> s_items = m_pTreeListResultados->GetPublicChildren(eid);
						std::set<std::string> listaModalidad;
						bool forceInit = true;
						bool questionMade = false;
						for (std::list<wxTreeItemId>::iterator ititem = s_items.begin(); ititem != s_items.end(); ++ititem) {
							wxTreeItemId cid = *ititem;

							std::string uidSerie = std::string(m_pTreeListResultados->GetItemText(cid, COLUMNA_UID).ToUTF8());
							std::string modalidadSerie = std::string(m_pTreeListResultados->GetItemText(cid, COLUMNA_MODALIDAD).ToUTF8());
							if (!uidSerie.empty()) { // La serie esta desplegada
								if( IsAllowedToDownload(modalidadSerie) ) {
									if (!questionMade && m_pDownloadPanel->FindDownload(uidSerie)) {
										forceInit = wxMessageBox(_("Series were already in the download queue.\nDo you want to force download?"),_("Download warning"),wxICON_INFORMATION|wxYES_NO) == wxYES;
										questionMade = true;
									}

									std::string descSerie = std::string( (m_pTreeListResultados->GetItemText(cid) + _T("(") + m_pTreeListResultados->GetItemText(cid, COLUMNA_MODALIDAD) + _T(")") ).ToUTF8());
									bool downloaded = m_pDownloadPanel->AddDownload(server, descPaciente, descSerie, modalidadSerie,forceInit, true, uidStudy, uidSerie);
									m_pTreeListResultados->SetItemBold(cid, downloaded);
									numSeriesDescargadas++;
								} else {
									listaModalidad.insert( modalidadSerie );
								}
							}
						}
						if (numSeriesDescargadas == 0 && listaModalidad.empty())
						{
							// Desplegamos la serie.

							wxTreeItemId item = seleccion;
							// >>------- Es un cut&paste del evento OnTreeItemExpanded, pero mejor esto que complicar la interfaz invocandolo directamente (lockers, omision de evento, reset de estado de la auto descarga de series , etc..)
							//se cancela el anterior comando y se contrae el item expandido
							if(item && item.IsOk()){
								//si el abuelo del item es root => consultar
								m_AutoAddSeries = true;
								m_AutoAddSeriesItem = item;
							}

							if(m_pComandoPACS != NULL)
							{
								GNC::Entorno::Instance()->GetControladorComandos()->AbortarComando(m_pComandoPACS, false);
								m_pComandoPACS = NULL;

								if(m_lastExpanded.IsOk()) {
									m_pTreeListResultados->Collapse(m_lastExpanded);
									m_lastExpanded.Unset();
								}
							}
							std::string server = GetServerSeleccionado();

							if(server=="") {
								return;
							}

							GADAPI::ComandoPACSParams * pParams = new GADAPI::ComandoPACSParams(
								"",
								"",
								std::string(m_pTreeListResultados->GetItemText(item,COLUMNA_UID).ToUTF8()),
								"",
								GetModalities(),
								"",
								"",
								"",
								"",server, GADAPI::ComandoPACSParams::TA_Serie, m_pModeloDicom, this);

							m_pComandoPACS = new GADAPI::ComandoPACS(pParams);
							GNC::Entorno::Instance()->GetControladorComandos()->ProcessAsync(_Std("Exploring PACS..."),m_pComandoPACS, this);
							m_pTextControlField->ShowCancelButton(true);
							ShowAnimation(true);
						}
						else if ( !listaModalidad.empty() )
						{
							std::ostringstream ostr;
							ostr << _Std("You are not allowed to download this kind of modalities (");
							bool primero = true;
							for (std::set<std::string>::iterator it = listaModalidad.begin(); it != listaModalidad.end(); ++it) {
								if (primero) {
									ostr << (*it);
									primero = false;
								}
								else {
									ostr << ", " << (*it);
								}
							}
							ostr << ")";
							wxMessageBox(wxString::FromUTF8( ostr.str().c_str() ), _("Modality download error"), wxICON_ERROR);
						}
					}//lanzar busqueda
				}//series mode
				//fin estudio
			} else {
				//estamos en una serie
				//std::string uidPaciente = std::string(m_pTreeListResultados->GetItemText(m_pTreeListResultados->GetItemParent(m_pTreeListResultados->GetItemParent(seleccion)), COLUMNA_UID).ToUTF8());
				std::string descPaciente = std::string(m_pTreeListResultados->GetItemText(m_pTreeListResultados->GetItemParent(m_pTreeListResultados->GetItemParent(seleccion))).ToUTF8());
				std::string uidStudy = std::string(m_pTreeListResultados->GetItemText(m_pTreeListResultados->GetItemParent(seleccion), COLUMNA_UID).ToUTF8());

				std::string uidSerie = std::string(m_pTreeListResultados->GetItemText(seleccion, COLUMNA_UID).ToUTF8());
				std::string descSerie = std::string( (m_pTreeListResultados->GetItemText(seleccion) + _T("(") + m_pTreeListResultados->GetItemText(seleccion, COLUMNA_MODALIDAD) + _T(")") ).ToUTF8());
				std::string modSerie =  std::string( m_pTreeListResultados->GetItemText(seleccion, COLUMNA_MODALIDAD ).ToUTF8());

				if (!modSerie.empty()) {
					if(! IsAllowedToDownload(modSerie)) {
						LOG_ERROR("GUI/Adquisition", _Std("Download of modality ") << modSerie << _Std(" not allowed"));
						wxMessageBox(_("You are not allowed to download this kind of modalities."),_("Modality download error"),wxICON_ERROR);
					}
					else {
						bool forceInit = true;
						if (m_pDownloadPanel->FindDownload(uidSerie)) {
							forceInit = wxMessageBox(_("Series were already in the download queue.\nDo you want to force download?"),_("Download warning"),wxICON_INFORMATION|wxYES_NO) == wxYES;
						}

						bool downloaded = m_pDownloadPanel->AddDownload(GetServerSeleccionado(), descPaciente, descSerie, modSerie, forceInit, true, uidStudy, uidSerie);
						m_pTreeListResultados->SetItemBold(seleccion, downloaded);
					}
				}
			}
		}
		else {
			return;
		}
	}
}

// Shows a dialog with the properties of selected treelist item
void GNC::GUI::DialogoAdquisicion::ShowProperties()
{
	wxTreeItemId selection = m_pTreeListResultados->GetSelection();

	if(selection.IsOk()){
		GNC::GUI::wxPropiedades::TListaMapasPropiedades listaMapas;

		wxTreeItemId patientTreeItemId;
		wxTreeItemId studyTreeItemId;
		wxTreeItemId serieTreeItemId;

		if(m_pTreeListResultados->GetItemParent(selection) == m_pTreeListResultados->GetRootItem()){
			//Patient Level
			patientTreeItemId = selection;
		}
		else if(m_pTreeListResultados->GetItemParent(m_pTreeListResultados->GetItemParent(selection)) == m_pTreeListResultados->GetRootItem()){
			studyTreeItemId   = selection;
			patientTreeItemId = m_pTreeListResultados->GetItemParent(selection);

		}
		else {
			serieTreeItemId   = selection;
			studyTreeItemId   = m_pTreeListResultados->GetItemParent(selection);
			patientTreeItemId = m_pTreeListResultados->GetItemParent(studyTreeItemId);
		}

		if (patientTreeItemId.IsOk()) {
			GNC::GUI::wxPropiedades::TMapaPropiedades mapaPropiedades;
			mapaPropiedades[_Std("Patient's Id")]   = std::string(m_pTreeListResultados->GetItemText(patientTreeItemId, COLUMNA_UID).ToUTF8());
			listaMapas.push_back(mapaPropiedades);
		}
		if (studyTreeItemId.IsOk()) {
			GNC::GUI::wxPropiedades::TMapaPropiedades mapaPropiedades;
			mapaPropiedades[_Std("Study Instance UID")] = std::string(m_pTreeListResultados->GetItemText(studyTreeItemId, COLUMNA_UID).ToUTF8());
			mapaPropiedades[_Std("Accession number")]   = std::string(m_pTreeListResultados->GetItemText(studyTreeItemId, COLUMNA_ACCNUMBER).ToUTF8());
			mapaPropiedades[_Std("Study date")] = std::string(m_pTreeListResultados->GetItemText(studyTreeItemId, COLUMNA_FECHA).ToUTF8());
			listaMapas.push_back(mapaPropiedades);
		}
		if (serieTreeItemId.IsOk()) {
			GNC::GUI::wxPropiedades::TMapaPropiedades mapaPropiedades;
			mapaPropiedades[_Std("Series Instance UID")] = std::string(m_pTreeListResultados->GetItemText(serieTreeItemId, COLUMNA_UID).ToUTF8());
			mapaPropiedades[_Std("Modality")] = std::string(m_pTreeListResultados->GetItemText(serieTreeItemId, COLUMNA_MODALIDAD).ToUTF8());
			mapaPropiedades[_Std("Series date")] = std::string(m_pTreeListResultados->GetItemText(serieTreeItemId, COLUMNA_FECHA).ToUTF8());

			listaMapas.push_back(mapaPropiedades);
		}

		GNC::GUI::wxPropiedades* pProp = new GNC::GUI::wxPropiedades(this, _Std("search results"), listaMapas);
		//increments width
		wxSize size = pProp->GetSize();
		size.x = 500;
		pProp->SetSize(size);
		pProp->Show();

	}

}

bool GNC::GUI::DialogoAdquisicion::IsAllowedToDownload(const std::string& modality)
{
	if ((GNC::GCS::IControladorPermisos::Instance()->Get("core.pacs.download", "all"))) {
		return true;
	} else {
		//split with \ bar
		wxStringTokenizer tknz(wxString::FromUTF8(modality.c_str()), wxT("\\"));
		std::list<std::string> modalities;
		while (tknz.HasMoreTokens()) {
			modalities.push_back(std::string(tknz.GetNextToken().ToUTF8()));
		}
		bool value = true;
		for (std::list<std::string>::iterator it =modalities.begin(); it != modalities.end(); ++it) {
			value = value && GNC::GCS::IControladorPermisos::Instance()->Get("core.pacs.download", (*it));
		}
		return value;
	}
}


void GNC::GUI::DialogoAdquisicion::ShowAnimation(bool show)
{
	m_pAnimation->Show(show);
	m_pPanelPACS->Layout();
	m_pPanelPACS->Refresh(true);
	if (show) {
		m_pAnimation->Play();
	} else {
		m_pAnimation->Stop();
	}
}


void GNC::GUI::DialogoAdquisicion::LimpiarBusquedas(bool /*lock*/) {

	/*
	GNC::GCS::ILocker* pLocker = NULL;
	if (lock )
	pLocker = new GNC::GCS::ILocker(m_TreeListResultadosLocker);
	*/

	m_pTreeListResultados->DeleteRoot();
	m_pTreeListResultados->AddRoot(wxT("Top"));
	m_pModeloDicom = GNC::GCS::Ptr<IModeloDicom>(new IModeloDicom());

	/*
	if (pLocker != NULL) {
	delete pLocker;
	}
	*/

}

//endregion


//---------------------------------------------------------------------------
//region realizacion de la interfaz IComandoPACSNotificador
void GNC::GUI::DialogoAdquisicion::PACSCargarListado(IModeloDicom * pModelo)
{
	{
		//GNC::GCS::ILocker locker(m_TreeListResultadosLocker);
		m_pTextControlField->ShowCancelButton(false);
		ShowAnimation(false);
		if(m_pComandoPACS == NULL)
		{
			return;
		}

		if (m_pComandoPACS->m_pPACSParams->m_Ambito == GADAPI::ComandoPACSParams::TA_Serie)
		{
			wxTreeItemId pacienteTreeId;
			wxTreeItemId estudioTreeId;

			m_lastExpanded.Unset();
			//actualizar el arbol
			const IModeloEstudio* estudio = NULL;
			pModelo->BuscarEstudio(m_pComandoPACS->m_pPACSParams->m_studyUID,&estudio);

			m_pComandoPACS = NULL;

			if (estudio != NULL) {
				std::set<std::string> listaModalidad;
				{//begin freeze/thaw
					Freeze();
					Refresh(true);
					{
						bool encontrado = false;
						wxString wxUIDEstudio = wxString::FromUTF8(estudio->GetUID().c_str());

						std::list<wxTreeItemId> p_items = m_pTreeListResultados->GetPublicChildren(m_pTreeListResultados->GetRootItem());
						for (std::list<wxTreeItemId>::iterator ititem = p_items.begin(); ititem != p_items.end() && !encontrado; ++ititem) {
							pacienteTreeId = *ititem;

							std::list<wxTreeItemId> e_items = m_pTreeListResultados->GetPublicChildren(pacienteTreeId);
							for (std::list<wxTreeItemId>::iterator ititem = e_items.begin(); ititem != e_items.end() && !encontrado; ++ititem) {
								estudioTreeId = *ititem;

								if(m_pTreeListResultados->GetItemText(estudioTreeId,COLUMNA_UID) == wxUIDEstudio) {
									encontrado = true;
									break;
								}
							}
						}
					}

					if(estudioTreeId.IsOk() && estudio->ListaSeries().size() > 0) {
						m_pTreeListResultados->DeleteChildren(estudioTreeId);
						bool forceInit = true;
						bool questionMade = false;

						for (IModeloEstudio::ListaSeriesType::const_iterator it3 = estudio->ListaSeries().begin(); it3 != estudio->ListaSeries().end(); ++it3) {
							const IModeloSerie& s = *it3;
							wxString uidSerie = wxString::FromUTF8(s.GetUID().c_str());
							wxString numeroDeImagenes = wxString::FromUTF8(s.GetNumero().c_str());
							wxString tipoSerie = wxString::FromUTF8(s.GetTipo().c_str());
							wxString descripcionSerie = wxString::FromUTF8(s.GetDescripcion().c_str());

							wxDateTime fecha;
							wxDateTime hora;
							hora.ParseFormat( wxString::FromUTF8( (s.GetHora()).c_str() ).GetData(), wxT("%H%M%S"), wxDefaultDateTime);
							fecha.ParseFormat( wxString::FromUTF8( (s.GetFecha()).c_str() ).GetData(), wxT("%Y%m%d"), wxDefaultDateTime);

							wxString fechaStr;

							if(fecha.IsValid()){
								if (hora.IsValid()) {

									fecha.SetHour(hora.GetHour());
									fecha.SetMinute(hora.GetMinute());
									fecha.SetSecond(hora.GetSecond());

									fechaStr = wxString(fecha.Format(_("%m/%d/%Y %H:%M:%S"), wxDateTime::TimeZone(wxDateTime::GMT1)));
								}
								else {
									fechaStr = wxString(fecha.Format(_("%m/%d/%Y 00:00:00"), wxDateTime::TimeZone(wxDateTime::GMT1)));
								}
							}
							else {
								fechaStr = _("00/00/0000 00:00:00");
							}


							wxTreeItemId serieTreeId;
							if (descripcionSerie.IsEmpty()) {
								serieTreeId = m_pTreeListResultados->AppendItem(estudioTreeId, _("Untitled"));
							} else {
								serieTreeId = m_pTreeListResultados->AppendItem(estudioTreeId, descripcionSerie);
							}
							m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_MODALIDAD, tipoSerie);

							m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_FECHA, fechaStr);

							m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_MEDICO, wxString::FromUTF8(s.GetDoctor().c_str()));
							m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_UID_VISIBLE, uidSerie);
							m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_UID, uidSerie);
							m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_ACCNUMBER, wxString::FromUTF8(estudio->GetAccNumber().c_str()));

							m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_Normal);
							m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_Selected);
							m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_Expanded);
							m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_SelectedExpanded);

							if (m_AutoAddSeries) {

								//std::string uidPaciente = std::string(m_pTreeListResultados->GetItemText(pacienteTreeId, COLUMNA_UID).ToUTF8());
								std::string descPaciente = std::string(m_pTreeListResultados->GetItemText(pacienteTreeId).ToUTF8());
								std::string uidStudy = std::string(m_pTreeListResultados->GetItemText(estudioTreeId, COLUMNA_UID).ToUTF8());

								std::string uidSerie = std::string(m_pTreeListResultados->GetItemText(serieTreeId, COLUMNA_UID).ToUTF8());
								std::string descSerie = std::string( (m_pTreeListResultados->GetItemText(serieTreeId) + _T("(") + m_pTreeListResultados->GetItemText(serieTreeId, COLUMNA_MODALIDAD) + _T(")") ).ToUTF8());

								std::string modalidadSerie = std::string(m_pTreeListResultados->GetItemText(serieTreeId, COLUMNA_MODALIDAD).ToUTF8());

								if( IsAllowedToDownload( modalidadSerie) ) {
									if (!questionMade && m_pDownloadPanel->FindDownload(uidSerie)) {
										Thaw();
										forceInit = wxMessageBox(_("Series were already in the download queue.\nDo you want to force download?"),_("Download warning"),wxICON_INFORMATION|wxYES_NO) == wxYES;
										Freeze();
										questionMade = true;
									}

									bool downloaded = m_pDownloadPanel->AddDownload(GetServerSeleccionado(), descPaciente, descSerie, modalidadSerie,forceInit, true, uidStudy, uidSerie);
									m_pTreeListResultados->SetItemBold(serieTreeId, downloaded);
								} else {
									listaModalidad.insert(modalidadSerie);
								}
							}

						}
						if (m_AutoAddSeries) {
							m_AutoAddSeries = false;
							m_AutoAddSeriesItem = NULL;
						}
						m_pTreeListResultados->SortChildren(estudioTreeId);
						m_pTreeListResultados->Expand(estudioTreeId);

					} else if (estudioTreeId.IsOk()) {
						m_pTreeListResultados->Collapse(estudioTreeId);
					}
					Thaw();
				} //end freeze

				if ( !listaModalidad.empty() ) {
					std::ostringstream ostr;
					ostr << _Std("You are not allowed to download this kind of modalities (");
					bool primero = true;
					for (std::set<std::string>::iterator it = listaModalidad.begin(); it != listaModalidad.end(); ++it) {
						if (primero) {
							ostr << (*it);
							primero = false;
						} else {
							ostr << ", " << (*it);
						}
					}
					ostr << ")";
					wxMessageBox(wxString::FromUTF8( ostr.str().c_str() ), _("Modality download error"), wxICON_ERROR);
				}
			}
		}
		else
		{
			//rellenar el arbol


			wxTreeItemId pacienteTreeId;
			wxTreeItemId estudioTreeId;
			wxTreeItemId serieTreeId;

			if (m_pComandoPACS->m_pPACSParams->m_error.size() > 0) {
				m_pComandoPACS = NULL;
				return;
			}
			else if(pModelo->ListaPacientes().size() == 0){
				if (!m_pComandoPACS->EstaAbortado()) {
					LimpiarBusquedas(false);
					wxTreeItemId topTreeId = m_pTreeListResultados->GetRootItem();
					if (! topTreeId || ! topTreeId.IsOk() ) {
						topTreeId = m_pTreeListResultados->AddRoot(wxT("Top"));
					}
					m_pTreeListResultados->AppendItem(topTreeId, _("No results found"));
				}
				m_pComandoPACS = NULL;
				return;
			}

			m_pComandoPACS = NULL;

			LimpiarBusquedas(false);

			wxTreeItemId topTreeId = m_pTreeListResultados->GetRootItem();
			if (! topTreeId || ! topTreeId.IsOk() ) {
				topTreeId = m_pTreeListResultados->AddRoot(wxT("Top"));
			}

			if (!topTreeId) {
				m_pComandoPACS = NULL;
				return;
			}

			{

				wxWindowDisabler disableAll;
				Freeze();
				//Refresh(true);

				for (IModeloDicom::ListaPacientesType::const_iterator it = pModelo->ListaPacientes().begin(); it != pModelo->ListaPacientes().end(); ++it) {
					const IModeloPaciente& p = *it;
					std::string pacienteNombre = p.GetNombre() + " (" + p.GetUID() + ")";
					wxString nombrePaciente = wxString::FromUTF8(pacienteNombre.c_str());
					wxString uidPaciente = wxString::FromUTF8(p.GetUID().c_str());
					//columnas

					bool notfound = true;
					wxTreeItemId tid = topTreeId;
					std::list<wxTreeItemId> p_items = m_pTreeListResultados->GetPublicChildren(topTreeId);
					for (std::list<wxTreeItemId>::iterator ititem = p_items.begin(); ititem != p_items.end(); ++ititem) {
						wxTreeItemId cid = *ititem;
						if (
							m_pTreeListResultados->GetItemText(cid) == nombrePaciente &&
							m_pTreeListResultados->GetItemText(cid, COLUMNA_UID) == uidPaciente
							) {
								notfound = false;
								pacienteTreeId = cid;
						}
					}

					if (notfound) {
						pacienteTreeId = m_pTreeListResultados->AppendItem(topTreeId, nombrePaciente);
						m_pTreeListResultados->SetItemText(pacienteTreeId, COLUMNA_UID, uidPaciente);
						//
						// Estilo
						m_pTreeListResultados->SetItemBold(pacienteTreeId, true);
						m_pTreeListResultados->SetItemTextColour(pacienteTreeId, *wxBLUE);

						//iconos
						int icono = 0;
						if(p.GetSexo() == "M") {
							icono = ICONO_HOMBRE;
						} else if(p.GetSexo() == "F") {
							icono = ICONO_MUJER;
						} else {
							icono = ICONO_OTRO;
						}

						m_pTreeListResultados->SetItemImage(pacienteTreeId,icono,wxTreeItemIcon_Normal);
						m_pTreeListResultados->SetItemImage(pacienteTreeId,icono,wxTreeItemIcon_Selected);
						m_pTreeListResultados->SetItemImage(pacienteTreeId,icono,wxTreeItemIcon_Expanded);
						m_pTreeListResultados->SetItemImage(pacienteTreeId,icono,wxTreeItemIcon_SelectedExpanded);
					}

					if (!pacienteTreeId) {
						continue;
					}
					//ESTUDIOS
					for (IModeloPaciente::ListaEstudiosType::const_iterator it2 = p.ListaEstudios().begin(); it2 != p.ListaEstudios().end(); ++it2) {
						const IModeloEstudio& e = *it2;
						wxDateTime fecha;
						wxDateTime hora;
						hora.ParseFormat( wxString::FromUTF8( (e.GetHora()).c_str() ).GetData(), wxT("%H%M%S"), wxDefaultDateTime);
						fecha.ParseFormat( wxString::FromUTF8( (e.GetFecha()).c_str() ).GetData(), wxT("%Y%m%d"), wxDefaultDateTime);

						wxString modalidadEstudio = wxString::FromUTF8(e.GetModalidad().c_str());
						wxString uidEstudio = wxString::FromUTF8(e.GetUID().c_str());
						wxString descripcionEstudio = wxString::FromUTF8(e.GetDescripcion().c_str());
						wxString AccNumber = wxString::FromUTF8(e.GetAccNumber().c_str());
						wxString medicoEstudio = wxString::FromUTF8(e.GetDoctor().c_str());

						wxString fechaStr;

						if(fecha.IsValid()){
							if (hora.IsValid()) {

								fecha.SetHour(hora.GetHour());
								fecha.SetMinute(hora.GetMinute());
								fecha.SetSecond(hora.GetSecond());

								fechaStr = wxString(fecha.Format(_("%m/%d/%Y %H:%M:%S"), wxDateTime::TimeZone(wxDateTime::GMT1)));
							}
							else {
								fechaStr = wxString(fecha.Format(_("%m/%d/%Y 00:00:00"), wxDateTime::TimeZone(wxDateTime::GMT1)));
							}
						}
						else {
							fechaStr = wxT("00/00/0000 00:00:00");
						}

						std::list<wxTreeItemId> e_items = m_pTreeListResultados->GetPublicChildren(pacienteTreeId);
						for (std::list<wxTreeItemId>::iterator ititem = e_items.begin(); ititem != e_items.end(); ++ititem) {
							wxTreeItemId cid = *ititem;
							if (
								m_pTreeListResultados->GetItemText(cid) == descripcionEstudio &&
								m_pTreeListResultados->GetItemText(cid, COLUMNA_MODALIDAD) == modalidadEstudio&&
								m_pTreeListResultados->GetItemText(cid, COLUMNA_FECHA) == fechaStr &&
								m_pTreeListResultados->GetItemText(cid, COLUMNA_MEDICO) == medicoEstudio &&
								m_pTreeListResultados->GetItemText(cid, COLUMNA_UID_VISIBLE) == uidEstudio &&
								m_pTreeListResultados->GetItemText(cid, COLUMNA_UID) == uidEstudio &&
								m_pTreeListResultados->GetItemText(cid, COLUMNA_ACCNUMBER) == AccNumber
								) {
									notfound = false;
									estudioTreeId = cid;
							}
						}

						if (notfound) {
							//columnas
							if (descripcionEstudio.IsEmpty()) {
								estudioTreeId = m_pTreeListResultados->AppendItem(pacienteTreeId, _("Untitled"));
							} else {
								estudioTreeId = m_pTreeListResultados->AppendItem(pacienteTreeId, descripcionEstudio);
							}
							m_pTreeListResultados->SetItemText(estudioTreeId, COLUMNA_MODALIDAD, modalidadEstudio);
							m_pTreeListResultados->SetItemText(estudioTreeId, COLUMNA_FECHA, fechaStr);

							m_pTreeListResultados->SetItemText(estudioTreeId, COLUMNA_MEDICO, medicoEstudio);
							m_pTreeListResultados->SetItemText(estudioTreeId, COLUMNA_UID_VISIBLE, uidEstudio);
							m_pTreeListResultados->SetItemText(estudioTreeId, COLUMNA_UID, uidEstudio);
							m_pTreeListResultados->SetItemText(estudioTreeId, COLUMNA_ACCNUMBER, AccNumber);
							//

							//ICONOS...
							m_pTreeListResultados->SetItemImage(estudioTreeId,ICONO_ESTUDIO,wxTreeItemIcon_Normal);
							m_pTreeListResultados->SetItemImage(estudioTreeId,ICONO_ESTUDIO,wxTreeItemIcon_Selected);
							m_pTreeListResultados->SetItemImage(estudioTreeId,ICONO_ESTUDIO,wxTreeItemIcon_Expanded);
							m_pTreeListResultados->SetItemImage(estudioTreeId,ICONO_ESTUDIO,wxTreeItemIcon_SelectedExpanded);
						}

						if (!estudioTreeId) {
							continue;
						}
						
						if (m_Mode == TD_SERIES) 
						{
							for (IModeloEstudio::ListaSeriesType::const_iterator it3 = e.ListaSeries().begin(); it3 != e.ListaSeries().end(); ++it3) {
								const IModeloSerie& s = *it3;
								wxString uidSerie = wxString::FromUTF8(s.GetUID().c_str());
								wxString numeroDeImagenes = wxString::FromUTF8(s.GetNumero().c_str());
								wxString tipoSerie = wxString::FromUTF8(s.GetTipo().c_str());
								wxString descripcionSerie = wxString::FromUTF8(s.GetDescripcion().c_str());
								wxString medicoSerie = wxString::FromUTF8(s.GetDoctor().c_str());
								wxDateTime fechaSerie;
								wxDateTime horaSerie;
								hora.ParseFormat( wxString::FromUTF8( (s.GetHora()).c_str() ).GetData(), wxT("%H%M%S"), wxDefaultDateTime);
								fecha.ParseFormat( wxString::FromUTF8( (s.GetFecha()).c_str() ).GetData(), wxT("%Y%m%d"), wxDefaultDateTime);

								wxString fechaSerieStr;

								if(fechaSerie.IsValid()){
									if (horaSerie.IsValid()) {
										fechaSerie.SetHour(horaSerie.GetHour());
										fechaSerie.SetMinute(horaSerie.GetMinute());
										fechaSerie.SetSecond(horaSerie.GetSecond());

										fechaSerieStr = wxString(fechaSerie.Format(_("%m/%d/%Y %H:%M:%S"), wxDateTime::TimeZone(wxDateTime::GMT1)));
									}
									else {
										fechaSerieStr = wxString(fechaSerie.Format(_("%m/%d/%Y 00:00:00"), wxDateTime::TimeZone(wxDateTime::GMT1)));
									}
								}
								else {
									fechaSerieStr = wxT("00/00/0000 00:00:00");
								}

								std::list<wxTreeItemId> s_items = m_pTreeListResultados->GetPublicChildren(estudioTreeId);
								for (std::list<wxTreeItemId>::iterator ititem = s_items.begin(); ititem != s_items.end(); ++ititem) {
									wxTreeItemId cid = *ititem;

									if (
										m_pTreeListResultados->GetItemText(cid) == descripcionSerie &&
										m_pTreeListResultados->GetItemText(cid, COLUMNA_MODALIDAD) == tipoSerie &&
										m_pTreeListResultados->GetItemText(cid, COLUMNA_FECHA) == fechaSerieStr &&
										m_pTreeListResultados->GetItemText(cid, COLUMNA_MEDICO) == medicoSerie &&
										m_pTreeListResultados->GetItemText(cid, COLUMNA_UID_VISIBLE) == uidSerie &&
										m_pTreeListResultados->GetItemText(cid, COLUMNA_UID) == uidSerie

										) {
											notfound = false;
											serieTreeId = cid;
									}
								}
								if (notfound) {

									serieTreeId = m_pTreeListResultados->AppendItem(estudioTreeId, descripcionSerie);

									m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_MODALIDAD, tipoSerie);
									m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_FECHA, fechaSerieStr);

									m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_MEDICO, medicoSerie);
									m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_UID_VISIBLE, uidSerie);
									m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_UID, uidSerie);
									m_pTreeListResultados->SetItemText(serieTreeId, COLUMNA_ACCNUMBER, AccNumber);

									m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_Normal);
									m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_Selected);
									m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_Expanded);
									m_pTreeListResultados->SetItemImage(serieTreeId,ICONO_SERIE,wxTreeItemIcon_SelectedExpanded);
								}
							}
							if(e.ListaSeries().size() == 0)
							{
								wxTreeItemId serieTreeId = m_pTreeListResultados->AppendItem(estudioTreeId, _("Searching..."));
							}
						}//end TD_SERIES
					}
					if (pModelo->ListaPacientes().size() < 2) {
						m_pTreeListResultados->Expand(pacienteTreeId);
					}
				}
				m_pTreeListResultados->SortChildren(m_pTreeListResultados->GetRootItem());
				Thaw();
			}
		}//else rellenar el arbol

		m_pTreeListResultados->Refresh(false);
		//m_pBotonBusqueda->SetAutoLayout(true);
	}
}


void GNC::GUI::DialogoAdquisicion::ProcesarEvento(GNC::GCS::Events::IEvent *evt)
{
	GNC::GCS::Events::EventoProgresoComando* pEvt = dynamic_cast<GNC::GCS::Events::EventoProgresoComando*> (evt);
	if (pEvt == NULL  || pEvt->GetComando() == NULL || pEvt->GetComando() != m_pComandoPACS) {
		return;
	}
	switch (pEvt->GetTipo()) {
case GNC::GCS::Events::EventoProgresoComando::TEP_Iniciado:
	break;
case GNC::GCS::Events::EventoProgresoComando::TEP_Progreso:
	break;
case GNC::GCS::Events::EventoProgresoComando::TEP_Finalizado:
	m_pTextControlField->ShowCancelButton(false);
	ShowAnimation(false);
	m_pComandoPACS = NULL;
	break;
case GNC::GCS::Events::EventoProgresoComando::TEP_Unknown:
	break;
	}
}

//endregion
