#ifndef STRINGUTILS_H
#define STRINGUTILS_H

#include <string.h>

// stricmp() is not available in Visual Studio 2013 and earlier
# if defined(_MSC_VER)
#define strtok_r strtok_s
# ifndef _CRT_SECURE_NO_DEPRECATE
# define _CRT_SECURE_NO_DEPRECATE (1)
# endif
# pragma warning(disable : 4996)
# endif

typedef enum ValueType {
    TYPE_INT,
    TYPE_FLOAT,
    TYPE_BOOL,
    TYPE_STRING,
    TYPE_UNKNOWN
} ValueType;


// Function to convert a string to a native type
template<typename T> T convertTo(const char* str);

// Specialization for int
template<> int convertTo<int>(const char* str) {
    return atoi(str);
}

// Specialization for float
template<> float convertTo<float>(const char* str) {
    return (float)atof(str);
}

// Specialization for bool
template<> bool convertTo<bool>(const char* str) {
    // Convert "true" or "1" to true, everything else to false
    return (stricmp(str, "true") == 0 || strcmp(str, "1") == 0);
}

// Specializations for int, float, bool, and possibly other types...

// Function to detect if a string is a valid integer
bool isInteger(const char* str) {
    if (*str == '-' || *str == '+') str++;  // Skip sign
    while (*str) {
        if (!isdigit(*str)) return false; // Check if all characters are digits
        str++;
    }
    return true;
}

// Function to detect if a string is a valid float
bool isFloat(const char* str) {
    bool hasPeriod = false;
    if (*str == '-' || *str == '+') str++;  // Skip sign
    while (*str) {
        if (*str == '.') {
            if (hasPeriod) return false; // Only one period allowed
            hasPeriod = true;
        } else if (!isdigit(*str)) {
            return false; // All other characters must be digits
        }
        str++;
    }
    return true;
}




// Function to detect if a string is a boolean
bool isBoolean(const char* str) {
    return (stricmp(str, "true") == 0 || stricmp(str, "false") == 0 || strcmp(str, "1") == 0 || strcmp(str, "0") == 0);
}


ValueType detectType(const char* str) {
    if (isInteger(str)) {
        return TYPE_INT;
    } else if (isFloat(str)) {
        return TYPE_FLOAT;
    } else if (isBoolean(str)) {
        return TYPE_BOOL;
    } else if (*str != '\0') { // Non-empty string considered as TYPE_STRING
        return TYPE_STRING;
    }
    return TYPE_UNKNOWN;
}

template<typename T, typename V>
void parseCommand(char* command, V val) { }

void processCommand(char* command) {
    char* saveptr = NULL;
    
    char test[160];
    strcpy(test, command);

    char* variable = strtok_s(test, "=", &saveptr);
    char* valueStr = strtok_r(NULL, "=", &saveptr);

    if (valueStr) {
        ValueType type = detectType(valueStr);

        switch (type) {
        case TYPE_INT: {
            int value = convertTo<int>(valueStr);
            parseCommand<int>(variable, value);
            break;
        }
        case TYPE_FLOAT: {
            float value = convertTo<float>(valueStr);
            parseCommand<float>(variable, value);
            break;
        }
        case TYPE_BOOL: {
            bool value = convertTo<bool>(valueStr);
            parseCommand<bool>(variable, value);
            break;
        }
        case TYPE_STRING: {
            // Handle strings or other types as needed
            break;
        }
        default:
            // Handle unknown type or add additional handling as needed
            break;
        }
    }
    else {
        // Handle "Value?" pattern or other patterns as needed
    }
}

#endif
