/*
 *  
 *  $Id: pacscontroller.h $
 *  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
 *
 *
 */
#pragma once

#include <api/api.h>
#include <api/controllers/ipacscontroller.h>
#include "dcmtk/istorecallback.h"


class Network;
class DicomServer;
namespace GNC{
	class IProxyNotificadorProgreso;
}

namespace GIL {
	namespace DICOM {
		class Service;
	}
}

namespace GIL {
	namespace DICOM {

		

		class EXTAPI PACSController : public IPACSController, public IStoreCallBack {
		public:

			// TODO: corregir
			typedef std::map<void*, IDICOMImg2DCM*> ListaInstanciasImg2DCMType;
			
			typedef std::map<void*, Network> NetworkConnectionList;

			static PACSController* Instance();
			static void FreeInstance();

			virtual IModeloDicom* BuscarPaciente(
				void* connectionKey,
				const std::string& serverId,
				const std::string& idPaciente,
				const std::string& nombrePaciente,
				const std::string& fechaNacimiento,
				IModeloDicom* pModelo,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual IModeloDicom* BuscarEstudio(
				void* connectionKey,
				const std::string& serverId,
				const std::string& idPaciente,
				const std::string& nombrePaciente,
				const std::string& idEstudio,
				const std::string& AccNumber,
				const std::string& modalidad,
				const std::string& fechaDesde,
				const std::string& fechaHasta,
				const std::string& timeFrom,
				const std::string& timeTo,
				const std::string& descripcionEstudio,
				const std::string& nombreEstacion,
				IModeloDicom* pModelo,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual IModeloDicom* BuscarSeries(
				void* connectionKey,
				const std::string& serverId,
				const std::string& idEstudio,
				const std::string& idSerie,
				IModeloDicom* pModelo,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual IModeloDicom* BuscarImagenes(
				void* connectionKey,
				const std::string& serverId,
				const std::string& idSerie,
				const std::string& idImagen,
				IModeloDicom* pModelo,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual void SubirArchivos(void* connectionKey, const std::string& serverId, const std::list<std::string>& pathsSubida, GNC::IProxyNotificadorProgreso* pNotificador, TipoTransferSyntaxEnvio transferSyntax);

			virtual void FillInQuery(const GIL::DICOM::DicomDataset& base, DcmDataset* query, DicomServer* server);
			
			virtual bool Print(
				void* connectionKey,
				const std::string& serverId,
				const GIL::DICOM::DicomDataset& film,
				const GIL::DICOM::DicomDataset& layout,
				const GIL::DICOM::DicomDataset& job,
				const std::list<std::string> files,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual bool ObtenerEstudio(
				void* connectionKey,
				const std::string& serverId,
				const GIL::DICOM::DicomDataset& base,
				IModeloDicom* pModelo,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual bool ObtenerSerie(
				void* connectionKey,
				const std::string& serverId,
				const GIL::DICOM::DicomDataset& base,
				IModeloDicom* pModelo,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual bool ObtenerImagen(
				void* connectionKey,
				const std::string& serverId,
				const GIL::DICOM::DicomDataset& base,
				IModeloDicom* pModelo,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			/** Gets the current server ID list */
			virtual void GetServerList(std::list<std::string>& list);

			/** Perform query */
			virtual bool Query(
				void* connectionKey,
				const std::string& abstractSyntax,
				const std::list<std::string>& transferSyntaxes,
				const GIL::DICOM::DicomDataset& query,
				int maxResultTagLen,
				std::list< GNC::GCS::Ptr<GIL::DICOM::DicomDataset> >& resultsWraper,
				const std::string& serverId,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual bool QueryRetrieve(
				void* connectionKey,
				const std::string& serverId,
				IModeloDicom* pModelo,
				const GIL::DICOM::DicomDataset& base,
				GNC::IProxyNotificadorProgreso* pNotificador
			);

			virtual GIL::DICOM::ICustomAssociation* CreateCustomAssociation(void* connectionKey, const std::string& ambitolog, GNC::IProxyNotificadorProgreso* pNotificador = NULL);
			virtual void DestroyCustomAssociation(GIL::DICOM::ICustomAssociation* assoc);

			virtual void StartServer();

			virtual void StopServer();

			virtual void  GetConnection(void* connectionKey);

			virtual void  ReleaseConnection(void* connectionKey);

			bool LeerDicomDir(const std::string& pathDicomDir, IModeloDicom* pModelo);

			virtual bool findAndGetTagFromFile(const std::string& ruta, unsigned short group, unsigned short element, std::string& value);

			virtual bool EsDICOM(const std::string& path, bool accept_dicomdir, bool accept_dicomfile) const;

			virtual bool EsPDF(const std::string& path) const;

			private:
			virtual bool GetRutaSerie(const std::string& uidPaciente, const std::string& uidEstudio, const std::string& uidSerie, std::string& ruta, bool crearDirectorios = true, bool temporal = false);
			virtual bool GetRutaImagen(const std::string& uidPaciente, const std::string& uidEstudio, const std::string& uidSerie, const std::string& uidImagen, std::string& ruta, bool crearDirectorios = true);
			public:
			virtual bool GetRutaImagenTemp(const std::string& uidPaciente, const std::string& uidEstudio, const std::string& uidSerie, const std::string& uidImagen, std::string& ruta, bool crearDirectorios = true);

//region "Interfaz IStoreCallBack"
			virtual void Store(const std::string& fileName, DcmDataset* dset);
//endregion

			void DumpFileElements(const std::string& rutaFichero, IInspectCallBack* callback);


//region "Métodos de Dicomización"

			IDICOMImg2DCM* CrearInstanciaDeImportacion();
			void LiberarInstanciaDeImportacion(IDICOMImg2DCM* instancia);

//endregion

//region "Métodos de carga/almacenamiento de DICOMS"

			IDICOMManager* CrearInstanciaDeDICOMManager();

			void LiberarInstanciaDeDICOMManager(IDICOMManager* instancia);

//endregion

		protected:
			PACSController();
			~PACSController();

			static void PurgarDirectorioTemporal();

		protected:

			static PACSController*     m_pInstance;
			ListaInstanciasImg2DCMType m_ListaInstanciasDicomImg2DCM;
			GIL::DICOM::Service*       m_pServiceInstance;

		private:
			void buildDicomDir();
		};
	};
};
