/*
 * OutputTask.c
 *
 *  Created on: 2020�~2��25��
 *      Author: 7564
 */

#include 	"OutputTask.h"

bool isOpen;

int InitComPort()
{
	int fd;
	struct termios tios;

	fd = open(priPortName, O_RDWR);
	if(fd<=0)
	{
		#ifdef SystemLogMessage
		DEBUG_ERROR("open 407 Communication port NG \n");
		#endif
		return -1;
	}
	ioctl (fd, TCGETS, &tios);
	tios.c_cflag = B115200| CS8 | CLOCAL | CREAD;
	tios.c_lflag = 0;
	tios.c_iflag = 0;
	tios.c_oflag = 0;
	tios.c_cc[VMIN]=0;
	tios.c_cc[VTIME]=(unsigned char)1;
	tios.c_lflag=0;
	tcflush(fd, TCIFLUSH);
	ioctl (fd, TCSETS, &tios);

	return fd;
}

unsigned long GetTimeoutValue(struct timeval _sour_time)
{
	struct timeval _end_time;
	gettimeofday(&_end_time, NULL);

	return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
}

void ShowMainMsg()
{
	printf("Max Vol : %f, Max Cur : %d, POW : %d \n", UnSafeDataInfo->PSU_VOLTAGE,
			UnSafeDataInfo->PSU_CURRENT, UnSafeDataInfo->PSU_POWER);
	printf("=> ");
}

void ChkButtonStatus()
{
	if (Button1 == PRESS && !leftBtnPush)
	{
		if(!leftBtnPush)
		{
			leftBtnPush = true;
			if (_charging_mode == CHARGING_MODE_STOP)
			{
				_charging_mode = CHARGING_MODE_START;
				printf("****************** Switch to Charging Mode ******************\n");
			}
		}
		else if (Button1 == RELEASE)
		{
			if(leftBtnPush)
			{
				leftBtnPush = false;
			}
		}
	}

	if (Button2 == PRESS && !rightBtnPush)
	{
		if(!rightBtnPush)
		{
			rightBtnPush = true;
			if (_charging_mode == CHARGING_MODE_START)
			{
				_charging_mode = CHARGING_MODE_TERMINATING;
				printf("****************** Switch to Stop Mode ******************\n");
			}
		}
		else if (Button2 == RELEASE)
		{
			if(rightBtnPush)
			{
				rightBtnPush = false;
			}
		}
	}
}

void GetModuleCountCallback(byte group, byte count)
{
	printf("group = %d, count = %d \n", group, count);
	if (group == SYSTEM_CMD)
		UnSafeDataInfo->PSU_COUNT = count;
}

void GetAvailableCapCallback(byte address, short maxVol, short minVol, short maxCur, short totalPow)
{
	int _groupPower = 0, _groupCurrent = 0;

	UnSafeDataInfo->PsuModule[address].PSU_VOLTAGE_INFO = maxVol;
	UnSafeDataInfo->PsuModule[address].PSU_CURRENT_INFO = maxCur;
	UnSafeDataInfo->PsuModule[address].PSU_POWER_INFO = totalPow;

	for (byte index = 0; index < UnSafeDataInfo->PSU_COUNT; index++)
	{
		_groupCurrent += UnSafeDataInfo->PsuModule[address].PSU_CURRENT_INFO;
		_groupPower += UnSafeDataInfo->PsuModule[address].PSU_POWER_INFO;
	}

	UnSafeDataInfo->PSU_VOLTAGE = maxVol;
	UnSafeDataInfo->PSU_CURRENT = _groupCurrent;
	UnSafeDataInfo->PSU_POWER = _groupPower;
}

void GetStatusCallback(byte group, byte address, byte temp, int alarm)
{
	printf("alarm = %d \n", alarm);
}

void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
{
	printf("vol1 = %d, vol2 = %d, vol3 = %d \n", vol1, vol2, vol3);
}

int CreateShareMemory()
{
	int MeterSMId;

	if ((MeterSMId = shmget(ShmTestKey,	sizeof(struct UnSafeData), IPC_CREAT | 0777)) < 0)
	{
		return 0;
	}
	else if ((UnSafeDataInfo = shmat(MeterSMId, NULL, 0))	== (void *) -1)
	{
		return 0;
	}
	memset(UnSafeDataInfo, 0, sizeof(struct UnSafeData));

	return 1;
}

static void get_char(char *word)
{
    fd_set rfds;
    struct timeval tv;

    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    tv.tv_sec = 0;
    tv.tv_usec = 10; //wait input timout time

    //if input
    if (select(1, &rfds, NULL, NULL, &tv) > 0)
    {
    	fgets(word, 128, stdin);
    }
}

void GetInputString()
{
	char word[128];
	char newString[7][10];
	int i, j, ctr;

	get_char(word);

	if (strlen(word) == 0)
	    return;
	//fgets(word, sizeof(word), stdin);

	j = 0;
	ctr = 0;
	for (i = 0; i <= (strlen(word)); i++) {
		if (word[i] == ' ' || word[i] == '\0' || word[i] == 10) {
			newString[ctr][j] = '\0';
			ctr++;
			j = 0;
		} else {
			newString[ctr][j] = word[i];
			j++;
		}
	}

	VOLTAGE = atof(newString[0]);
	CURRENT = atof(newString[1]);
	if (VOLTAGE <= UnSafeDataInfo->PSU_VOLTAGE && CURRENT <= UnSafeDataInfo->PSU_CURRENT)
	{
		//printf("OutputVol = %f, OutputCur = %f \n", VOLTAGE, CURRENT);
	}
	else
	{
		ShowMainMsg();
	}
}

void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
{
	//printf("address = %d, Iavail = %d, Vext = %d \n", address, Iavail, Vext);
}

void GetOutputAndTempCallback(byte address, unsigned short outputVol,
		unsigned short outputCur, unsigned short outputPower, unsigned char Temperature)
{
	//printf("***Output Value and Temp*** address = %d, Vol = %d, Cur = %d, Pow = %d, Temp = %d \n",
	//		address, outputVol, outputCur, outputPower, Temperature);
}

void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char status,
		unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4)
{
	//int alarm = (err2 << 24) | (err3 << 16) | (err4 << 8);

	// err2 == state 2
	// err3 == state 1
	// err4 == state 0
	//printf("***Status*** address = %d, alarm = %d \n", address, alarm);
//	printf("***Status*** address = %d, err1 = %d, err2 = %d, err3 = %d, err4 = %d \n",
//			address, err1,err2,err3,err4);
}

void GetModuleInputCallback(byte address, unsigned short inputR,
		unsigned short inputS, unsigned short inputT)
{

}

int main(void)
{
	isOpen =false;

	if(CreateShareMemory() == 0)
	{
		printf("CreateShareMemory fail. \n");
		return 0;
	}
	RefreshModuleCount(&GetModuleCountCallback);
	RefreshAvailableCap(&GetAvailableCapCallback);

	RefreshStatus(&GetStatusCallback);
	RefreshInputVol(&GetInputVoltageCallback);

	RefreshIavailable(&GetIavailableCallback);

	AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback);
	AutoMode_RefreshModuleStatus(&GetModuleStatusCallback);
	AutoMode_RefreshModuleInput(&GetModuleInputCallback);

	Uart1Fd = InitComPort();
	libInitialize = InitialCommunication();

	if (Uart1Fd < 0 || !libInitialize)
	{
		printf("Initial port fail. \n");
		return 0;
	}

	sleep(5);
	gettimeofday(&_cmdSubPriority_time, NULL);
	VOLTAGE = 0.0;
	CURRENT = 0.0;

	SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
//	while (1)
//	{
//		printf("++++++++++++++2++++++++++++++++++++++++++++++++++++++\n");
//		SetWalkInConfig(0, YES, 0);
//		SetWalkInConfig(1, NO, 0);
//		printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
//		sleep(1);
//	}
//
//	sleep(1);
//		printf("++++++++++++++2++++++++++++++++++++++++++++++++++++++\n");
//		SetWalkInConfig(SYSTEM_CMD, NO, 0);
//		printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
//	return 0;
	while (1)
	{
		GetInputGpioStatus();
		//ChkButtonStatus();
		// ���� Walk-in mode (default 5s -> 2s)
		SetWalkInConfig(SYSTEM_CMD, NO, 0);

		int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
		while(isGetCount == YES)
		{
			if (_charging_mode == CHARGING_MODE_START)
			{
				// ���o�Ҷ���X�B�w�q�y��O
				GetModuleIavailable(0);
			}

			GetInputString();
			if (VOLTAGE > 150 && CURRENT >= 0)
				_charging_mode = CHARGING_MODE_START;
			else
				_charging_mode = CHARGING_MODE_TERMINATING;
			//printf("_charging_mode = %d \n", _charging_mode);
			switch(_charging_mode)
			{
				case CHARGING_MODE_START:
				{
					//if (!isOpen)
					{
						//SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
						//FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
						SetDirModulePresentOutput(0,
												VOLTAGE * 10,
												CURRENT * 10,
												0x01,
												0x01);
					}
					//PresentOutputVol(SYSTEM_CMD, VOLTAGE * 10, CURRENT * 10);
				}
					break;
				case CHARGING_MODE_TERMINATING:
				{
					//if (isOpen)
					{
						SetDirModulePresentOutput(0,
							VOLTAGE * 10,
							CURRENT * 10,
							0x00,
							0x01);
						//SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
						//FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
					}
				}
					break;
			}
			//GetStatus(0);
			//GetModuleInput(0);
			sleep(1);
		}

		if (UnSafeDataInfo->PSU_COUNT <= 0)
		{
			if (time > 1000)
			{
				printf("Step 1 : GetModuleCount...... \n");
				GetModuleCount(SYSTEM_CMD);
				gettimeofday(&_cmdSubPriority_time, NULL);
			}
		}
		else if (time < 5000)
		{
			printf("Step 2 : GetModuleCap...... \n");
			GetModuleCap(0);

			SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
			FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
		}
		else
		{
			ShowMainMsg();
			isGetCount = YES;
		}

		sleep(1);
	}

	return 0;
}