#include "socketManager.h"
#include <time.h>


socketManager::socketManager()
{
	PORT = 5150;
	MSGSIZE = 1024;
}

socketManager::~socketManager()
{
	free(CTpath);
	free(rd);
}

void socketManager::get_CUDAdrr(const char * path)
{
	if (rd != NULL) {
		// 析构 释放GPU内存
		//free(rd);
		rd = NULL;
	}
	rd = new drr(path);
}

float* socketManager::get_FloatDRR(float rx, float ry, float rz, int dx, int dy, float threshold)
{
	if (rd == NULL)
		return NULL;
	return rd->cudaFloatDRR(rx, ry, rz, dx, dy, threshold);
}

unsigned char* socketManager::get_UCharDRR(float rx, float ry, float rz, int dx, int dy, float threshold)
{
	if (rd == NULL)
		return NULL;
	return rd->cudaUCharDRR(rx, ry, rz, dx, dy, threshold);
}


void socketManager::open_socket() {
	WSADATA wsaData;
	SOCKET sListen;
	SOCKET sClient;
	SOCKADDR_IN local;
	SOCKADDR_IN client;
	int ret;
	int iaddrSize = sizeof(SOCKADDR_IN);
	WSAStartup(0x0202, &wsaData);
	sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	local.sin_family = AF_INET;
	local.sin_port = htons(PORT);
	local.sin_addr.s_addr = htonl(INADDR_ANY);
	::bind(sListen, (struct sockaddr*) &local, sizeof(SOCKADDR_IN));
	listen(sListen, 1);

	char szMessage[1024];
	
	while (TRUE) {
		sClient = accept(sListen, (struct sockaddr*)&client, &iaddrSize);
		printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
		while (TRUE) {
			ret = recv(sClient, szMessage, MSGSIZE, 0);
			szMessage[ret] = '\0';
			if (ret > 4) {
				if (szMessage[0] == 'C' && szMessage[1] == 'T' && szMessage[2] == '(') {
					CTpath = new char[ret - 2];
					for (int i = 3; i < ret - 1; i++) {
						CTpath[i - 3] = szMessage[i];
					}
					CTpath[ret - 4] = '\0';
					/////// 导入CT数据
					try {
						get_CUDAdrr(CTpath);
					}
					catch(exception& e){
						printf("Failed to load the CT sequence\n");
						break;
					}
					const char* msg = "ct imported successfully";
					send(sClient, msg, strlen(msg), 0);
					///////
					printf("CT imported successfully :'%s'\n", CTpath);
				}
				else if (szMessage[0] == 'P' && szMessage[1] == 'A' &&
					szMessage[2] == 'R' && szMessage[3] == 'A' &&
					szMessage[4] == '(') {
					double time = (double)clock() / CLOCKS_PER_SEC;
					float * data = handleString(szMessage, ret);
					//////// 生成DRR
					try {
						unsigned char* object2D = get_UCharDRR(data[0], data[1], data[2], (int)data[3], (int)data[4], data[5]);
						send(sClient, (char*)object2D, sizeof(unsigned char)*(int)data[3] * (int)data[4], 0);
						free(object2D);
					}
					catch (exception& e) {
						printf("Failed to generate DRR, please check your parameters.\n");
						break;
					}
					////////
					printf("Create DRR image succeed: [%f, %f, %f, %d, %d, %f] ", data[0], data[1], data[2], (int)data[3], (int)data[4], data[5]);
					std::cout << ", time :" << (double)clock() / CLOCKS_PER_SEC - time << "s" << std::endl;
				}
				break;
			}
		}
		sClient = NULL;
	}
}

float* socketManager::handleString(char* szMessage, int ret) {
	float data[7];
	int k = 0;
	char* buf = new char[1024];
	int j = 0;
	for (int i = 5; i < ret - 1; i++) {
		if (szMessage[i] != ',' && k < 7) {
			buf[j] = szMessage[i];
			j++;
		}
		else {
			buf[j] = '\0';
			j = 0;
			data[k] = atof(buf);
			buf = new char[1024];
			k++;
		}
	}
	buf[j] = '\0';
	data[k] = atof(buf);
	return data;
}

