#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
//#include <math.h>
#define TEMPS 3
#define LOG 0

/*
const char *Locations[9] = {
	"/sys/class/hwmon/hwmon2/pwm1_enable",
	"/sys/class/hwmon/hwmon1/pwm1_enable",
	"/sys/class/hwmon/hwmon2/pwm3_enable",
	"/sys/class/hwmon/hwmon0/temp1_input",
	"/sys/class/hwmon/hwmon1/temp1_input",
	"/sys/class/hwmon/hwmon0/temp1_input",
	"/sys/class/hwmon/hwmon2/pwm1",
	"/sys/class/hwmon/hwmon1/pwm1",
	"/sys/class/hwmon/hwmon2/pwm3"
};
*/
const char *Enable[TEMPS] = {
	"/sys/class/hwmon/hwmon2/pwm1_enable",
	"/sys/class/hwmon/hwmon1/pwm1_enable",
	"/sys/class/hwmon/hwmon2/pwm3_enable"
};

const char *Temp[TEMPS] = {
	"/sys/class/hwmon/hwmon0/temp1_input",
	"/sys/class/hwmon/hwmon1/temp1_input",
	"/sys/class/hwmon/hwmon0/temp1_input"
};

const char *Pwm[TEMPS] = {
	"/sys/class/hwmon/hwmon2/pwm1",
	"/sys/class/hwmon/hwmon1/pwm1",
	"/sys/class/hwmon/hwmon2/pwm3"
};



struct fan_params {
	uint8_t pwm;
	uint8_t temp;
	uint8_t maxtemp;
	uint8_t mintemp;
	uint8_t medtemp;
	uint8_t maxpwm;
	uint8_t minpwm;
	uint8_t medpwm;
	uint8_t highpwm;
};

int main(int argc, char **argv){
	FILE *fp;

#if LOG==1
	FILE *log;
#endif
	uint8_t num1; //curpwm, curtemp;
	// cpu gpu sys
	struct fan_params Params[TEMPS] = {{0, 0, 50, 20, 40, 255, 85, 140, 200}, {0, 0, 60, 40, 50, 255, 50, 160, 200}, {0, 0, 50, 20, 40, 255, 100, 133, 200}};
	char linestring[7];

	//Enable pwm control
	for(num1=0; num1<TEMPS; num1++){
		if ( (fp = fopen(Enable[num1], "w")) ){
			fprintf(fp, "%u\n", 1 );
		}
		fclose(fp);
	}

	//open logdir
	//if ( (log = fopen("/gputemps.txt", "a")) == NULL){
	//	//fprintf(fp, "%u\n", 1 );
	//	fprintf( stderr, "Error opening log file\n");
	//}

	//Main loop
	while(1){

		//Read Temperatures
		for(num1=0; num1<TEMPS; num1++){
			Params[num1].temp = 100;
			if( ( fp = fopen(Temp[num1], "r" ) ) == NULL ) {
				fprintf( stderr, "Error opening %s\n", Temp[num1] );
			}else{
				if( fgets(linestring, sizeof(linestring), fp) == NULL){
					fprintf( stderr, "Error reading %s\n", Temp[num1] );
				}else{
					Params[num1].temp = atoi(linestring)/1000;
				}
			}
			fclose(fp);
			//Params[num1].temp = curtemp;
		}

		for(num1=0; num1<2; num1++){
			//if(num1==2){
			//	curpwm = Params[1].pwm>Params[0].pwm ? Params[1].pwm : Params[0].pwm;
			if(Params[num1].temp < Params[num1].mintemp){
				Params[num1].pwm = Params[num1].minpwm*Params[num1].temp/Params[num1].mintemp;
			}else if(Params[num1].temp < Params[num1].medtemp){
				Params[num1].pwm = Params[num1].medpwm*Params[num1].temp/Params[num1].medtemp;
			}else if(Params[num1].temp < Params[num1].maxtemp){
				Params[num1].pwm = Params[num1].highpwm*Params[num1].temp/Params[num1].maxtemp;
			}else{
				Params[num1].pwm = Params[num1].maxpwm;
			}
			//Params[num1].pwm = curpwm;
		}
		Params[num1].pwm = Params[1].pwm>Params[0].pwm ? Params[1].pwm : Params[0].pwm;

		for(num1=0; num1<TEMPS; num1++){
			if ( (fp = fopen(Pwm[num1], "w")) ){
				fprintf(fp, "%u\n", Params[num1].pwm );
//fprintf(fp, "%u\n", Params[num1].maxpwm );
			}
			fclose(fp);
		}
#if LOG==1
		if ( (log = fopen("/gputemps.txt", "a")) == NULL){
			fprintf( stderr, "Error opening log file\n");
		}
		fprintf(log, "%u %u\n", Params[1].temp, Params[1].pwm );
		fclose(log);
#endif

		//	Params[num1].pwm = curpwm;
		sleep(1);
	}
	//fclose(log);
	return 0;
}
