/**
 * @file vg_lite_tvg.cpp
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "../../lv_conf_internal.h"
#if LV_USE_DRAW_VG_LITE && LV_USE_VG_LITE_THORVG

#include "vg_lite.h"
#include "../../lvgl.h"
#include "../../libs/thorvg/thorvg.h"
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <thread>
#include <vector>

#if LV_VG_LITE_THORVG_YUV_SUPPORT
    #include <libyuv/convert_argb.h>
#endif

/*********************
 *      DEFINES
 *********************/

#define TVG_CANVAS_ENGINE CanvasEngine::Sw
#define TVG_COLOR(COLOR) B(COLOR), G(COLOR), R(COLOR), A(COLOR)
#define TVG_IS_VG_FMT_SUPPORT(fmt) ((fmt) == VG_LITE_BGRA8888 || (fmt) == VG_LITE_BGRX8888)

#define TVG_CHECK_RETURN_VG_ERROR(FUNC)                               \
    do {                                                              \
        Result res = FUNC;                                            \
        if (res != Result::Success) {                                 \
            LV_LOG_ERROR("Executed '" #FUNC "' error: %d", (int)res);                        \
            return vg_lite_error_conv(res);                           \
        }                                                             \
    } while (0)
#define TVG_CHECK_RETURN_RESULT(FUNC)                                 \
    do {                                                              \
        Result res = FUNC;                                            \
        if (res != Result::Success) {                                 \
            LV_LOG_ERROR("Executed '" #FUNC "' error: %d", (int)res);\
            return res;                                               \
        }                                                             \
    } while (0)

/* clang-format off */

#define IS_INDEX_FMT(fmt)           \
    ((fmt) == VG_LITE_INDEX_1       \
     || (fmt) == VG_LITE_INDEX_2 \
     || (fmt) == VG_LITE_INDEX_4 \
     || (fmt) == VG_LITE_INDEX_8)

#define VLC_GET_ARG(CUR, INDEX) vlc_get_arg((cur + (INDEX) * fmt_len), path->format);
#define VLC_GET_OP_CODE(ptr) (*((uint8_t*)ptr))
#define VLC_OP_ARG_LEN(OP, LEN) \
    case VLC_OP_##OP:           \
    return (LEN)

#define A(color) ((color) >> 24)
#define R(color) (((color) & 0x00ff0000) >> 16)
#define G(color) (((color) & 0x0000ff00) >> 8)
#define B(color) ((color) & 0xff)
#define ARGB(a, r, g, b) ((a) << 24) | ((r) << 16) | ((g) << 8) | (b)
#define MIN(a, b) (a) > (b) ? (b) : (a)
#define MAX(a, b) (a) > (b) ? (a) : (b)
#define UDIV255(x) (((x) * 0x8081U) >> 0x17)
#define LERP(v1, v2, w) ((v1) * (w) + (v2) * (1.0f - (w)))
#define CLAMP(x, min, max) (((x) < (min)) ? (min) : ((x) > (max)) ? (max) : (x))
#define COLOR_FROM_RAMP(ColorRamp) (((vg_lite_float_t*)ColorRamp) + 1)

#define VG_LITE_RETURN_ERROR(func)         \
    if ((error = func) != VG_LITE_SUCCESS) \
        return error

#define VG_LITE_ALIGN(number, align_bytes) \
    (((number) + ((align_bytes)-1)) & ~((align_bytes)-1))

#define VG_LITE_IS_ALIGNED(num, align) (((uintptr_t)(num) & ((align)-1)) == 0)

#define VG_LITE_IS_ALPHA_FORMAT(format) \
    ((format) == VG_LITE_A8 || (format) == VG_LITE_A4)

/* clang-format on */

/**********************
 *      TYPEDEFS
 **********************/

using namespace tvg;

#pragma pack(1)
typedef struct {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
} vg_color24_t;

typedef struct {
    uint16_t blue : 5;
    uint16_t green : 6;
    uint16_t red : 5;
} vg_color16_t;

typedef struct {
    vg_color16_t c;
    uint8_t alpha;
} vg_color16_alpha_t;

typedef struct {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
    uint8_t alpha;
} vg_color32_t;

typedef struct {
    vg_lite_float_t x;
    vg_lite_float_t y;
} vg_lite_fpoint_t;

#pragma pack()

class vg_lite_ctx
{
    public:
        std::unique_ptr<SwCanvas> canvas;
        void * target_buffer;
        void * tvg_target_buffer;
        vg_lite_uint32_t target_px_size;
        vg_lite_buffer_format_t target_format;
        vg_lite_rectangle_t scissor_rect;
        bool scissor_is_set;

    public:
        vg_lite_ctx()
            : target_buffer { nullptr }
            , tvg_target_buffer { nullptr }
            , target_px_size { 0 }
            , target_format { VG_LITE_BGRA8888 }
            , scissor_rect { 0, 0, 0, 0 }
            , scissor_is_set { false }
            , clut_2colors { 0 }
            , clut_4colors { 0 }
            , clut_16colors { 0 }
            , clut_256colors { 0 }
        {
            canvas = SwCanvas::gen();
        }

        vg_lite_uint32_t * get_image_buffer(vg_lite_uint32_t w, vg_lite_uint32_t h)
        {
            src_buffer.resize(w * h);
            return src_buffer.data();
        }

        vg_lite_uint32_t * get_temp_target_buffer(vg_lite_uint32_t w, vg_lite_uint32_t h)
        {
            vg_lite_uint32_t px_size = w * h;
            if(px_size > dest_buffer.size()) {
                dest_buffer.resize(w * h);
            }


#include <cmath>
#include "utility.h"
#include "lio_sam/cloud_info.h"

struct VelodynePointXYZIRT
{
    PCL_ADD_POINT4D
    PCL_ADD_INTENSITY;
    uint16_t ring;
    float time;
    uint16_t noise;
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;
POINT_CLOUD_REGISTER_POINT_STRUCT (VelodynePointXYZIRT,
    (float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity)
    (uint16_t, ring, ring) (float, time, time) (uint16_t, noise, noise)
)

struct OusterPointXYZIRT {
    PCL_ADD_POINT4D;
    float intensity;
    uint32_t t;
    uint16_t reflectivity;
    uint8_t ring;
    uint16_t noise;
    uint32_t range;
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;
POINT_CLOUD_REGISTER_POINT_STRUCT(OusterPointXYZIRT,
    (float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity)
    (uint32_t, t, t) (uint16_t, reflectivity, reflectivity)
    (uint8_t, ring, ring) (uint16_t, noise, noise) (uint32_t, range, range)
)

// Use the Velodyne point format as a common representation
using PointXYZIRT = VelodynePointXYZIRT;

const int queueLength = 2000;

class ImageProjection : public ParamServer
{
private:

    std::mutex imuLock;
    std::mutex odoLock;

    ros::Subscriber subLaserCloud;
    ros::Publisher  pubLaserCloud;

    ros::Publisher pubExtractedCloud;
    ros::Publisher pubLaserCloudInfo;

    ros::Subscriber subImu;
    std::deque<sensor_msgs::Imu> imuQueue;

    ros::Subscriber subOdom;
    std::deque<nav_msgs::Odometry> odomQueue;

    std::deque<sensor_msgs::PointCloud2> cloudQueue;
    sensor_msgs::PointCloud2 currentCloudMsg;

    double *imuTime = new double[queueLength];
    double *imuRotX = new double[queueLength];
    double *imuRotY = new double[queueLength];
    double *imuRotZ = new double[queueLength];

    int imuPointerCur;
    bool firstPointFlag;
    Eigen::Affine3f transStartInverse;

    pcl::PointCloud<PointXYZIRT>::Ptr laserCloudIn;
    pcl::PointCloud<OusterPointXYZIRT>::Ptr tmpOusterCloudIn;
    pcl::PointCloud<PointType>::Ptr   fullCloud;
    pcl::PointCloud<PointType>::Ptr   extractedCloud;

    int deskewFlag;
    cv::Mat rangeMat;

    bool odomDeskewFlag;
    float odomIncreX;
    float odomIncreY;
    float odomIncreZ;

    lio_sam::cloud_info cloudInfo;
    double timeScanCur;
    double timeScanEnd;
    std_msgs::Header cloudHeader;

public:
    ImageProjection():
    deskewFlag(0)
    {
        subImu        = nh.subscribe<sensor_msgs::Imu>(imuTopic, 2000, &ImageProjection::imuHandler, this, ros::TransportHints().tcpNoDelay());
        subOdom       = nh.subscribe<nav_msgs::Odometry>(odomTopic+"_incremental", 2000, &ImageProjection::odometryHandler, this, ros::TransportHints().tcpNoDelay());
        subLaserCloud = nh.subscribe<sensor_msgs::PointCloud2>(pointCloudTopic, 5, &ImageProjection::cloudHandler, this, ros::TransportHints().tcpNoDelay());

        pubExtractedCloud = nh.advertise<sensor_msgs::PointCloud2> ("lio_sam/deskew/cloud_deskewed", 1);
        pubLaserCloudInfo = nh.advertise<lio_sam::cloud_info> ("lio_sam/deskew/cloud_info", 1);

        allocateMemory();
        resetParameters();

        pcl::console::setVerbosityLevel(pcl::console::L_ERROR);
    }

    void allocateMemory()
    {
        laserCloudIn.reset(new pcl::PointCloud<PointXYZIRT>());
        tmpOusterCloudIn.reset(new pcl::PointCloud<OusterPointXYZIRT>());
        fullCloud.reset(new pcl::PointCloud<PointType>());
        extractedCloud.reset(new pcl::PointCloud<PointType>());

        fullCloud->points.resize(N_SCAN*Horizon_SCAN);

        cloudInfo.startRingIndex.assign(N_SCAN, 0);
        cloudInfo.endRingIndex.assign(N_SCAN, 0);

        cloudInfo.pointColInd.assign(N_SCAN*Horizon_SCAN, 0);
        cloudInfo.pointRange.assign(N_SCAN*Horizon_SCAN, 0);

        resetParameters();
    }

    void resetParameters()
    {
        laserCloudIn->clear();
        extractedCloud->clear();
        // reset range matrix for range image projection
        rangeMat = cv::Mat(N_SCAN, Horizon_SCAN, CV_32F, cv::Scalar::all(FLT_MAX));

        imuPointerCur = 0;
        firstPointFlag = true;
        odomDeskewFlag = false;

        for (int i = 0; i < queueLength; ++i)
        {
            imuTime[i] = 0;
            imuRotX[i] = 0;
            imuRotY[i] = 0;
            imuRotZ[i] = 0;
        }
    }

    ~ImageProjection(){}

    void imuHandler(const sensor_msgs::Imu::ConstPtr& imuMsg)
    {
        sensor_msgs::Imu thisImu = imuConverter(*imuMsg);

        std::lock_guard<std::mutex> lock1(imuLock);
        imuQueue.push_back(thisImu);

        // debug IMU data
        cout << std::setprecision(6);
        cout << "IMU acc: " << endl;
        cout << "x: " << thisImu.linear_acceleration.x <<
              ", y: " << thisImu.linear_acceleration.y <<
              ", z: " << thisImu.linear_acceleration.z << endl;
        cout << "IMU gyro: " << endl;
        cout << "x: " << thisImu.angular_velocity.x <<
              ", y: " << thisImu.angular_velocity.y <<


#include "DHT11.h"

static uint8_t _pin;   // store the pin connected to DHT11

void DHT11_begin(uint8_t pin) {
  _pin = pin;
}

// Function to read data from DHT11
bool DHT11_read(float *temperature, float *humidity) {
  uint8_t data[5] = {0};

  // ==== Start signal ====
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, LOW);
  delay(20);                     // at least 18ms
  digitalWrite(_pin, HIGH);
  delayMicroseconds(40);
  pinMode(_pin, INPUT);

  // ==== Sensor response ====
  while (digitalRead(_pin));
  while (!digitalRead(_pin));
  while (digitalRead(_pin));

  // ==== Read 40 bits ====
  for (int byteIndex = 0; byteIndex < 5; byteIndex++) {
    for (int bitIndex = 0; bitIndex < 8; bitIndex++) {
      while (!digitalRead(_pin));   // wait for HIGH
      unsigned long start = micros();

      while (digitalRead(_pin));    // wait for LOW
      unsigned long duration = micros() - start;

      if (duration > 40) {          // HIGH > 40µs = bit '1'
        data[byteIndex] |= (1 << (7 - bitIndex));
      }
    }
  }

  // ==== Verify checksum ====
  uint8_t checksum = data[0] + data[1] + data[2] + data[3];
  if (data[4] != checksum) {
    return false; // checksum error
  }

  // ==== Convert values ====
  *humidity = data[0] + (data[1] * 0.1);
  *temperature = data[2] + (data[3] * 0.1);

  return true;
}


#include "stylesheet.h"

stylesheet::stylesheet()
{
    one = "QPushButton {"
          "background-color: black;"
          "color: white;"
          "font-weight: bold;"
          "}"
          "QPushButton:hover {"
          "color: Black;"
          "background-color: white;"
          "}";
    labelModif = "QLabel {"
                 "font-weight: bold;"
                 "align-items: center;"
                 "}";
    BttnEntretient0 = "QPushButton {"
                      "background-color: #f4b6b6;"
                      "font-weight: bold;"
                      "}";
    BttnEntretient1 = "QPushButton {"
                      "background-color: #eb8585;"
                      "font-weight: bold;"
                      "}";
    BttnEntretient2 = "QPushButton {"
                      "background-color: red;"
                      "font-weight: bold;"
                      "}";
    Bttnnone = "QPushButton {"
               "background-color: white;"
               "color: gray;"
               "}";
    zoneRecherche = "QLineEdit {"
                    "border-radius: 8px;"
                    "border: 1px solid gray;"
                    "}";
    BttnGauche = "QPushButton {"
                 "border-radius: 5px;"
                 "border: 1px solid gray;"
                 ""
                 "}"
                 "QPushButton:hover {"
                 "background-color: gray;"
                 ""
                 "}";
    changeUtil = "QPushButton {"
                 "border-radius: 10px;"
                 "border: 1px solid black;"
                 "}"
                 "QPushButton:hover {"
                 "background-color: green;"
                 "}";
    quitUtil = "QPushButton:hover {"
               "background: red;"
               "}";
    quitU = "QPushButton {"
            "border-radius: 10px;"
            "border: 2px solid red;"
            "}";
}


#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
using namespace std;

int main(){
    map<string, int> karakterer = {
        {"Per", 5},
        {"Kari", 4},
        {"Ola", 6}
    };

    ofstream outfile("karakter.txt");
    if(outfile.is_open())
    {
        for(const auto& par : karakterer)
        {
            outfile << par.first << " : " << par.second << endl;
        }
        outfile.close();
    } else {
        cout << "Fil kunne ikke åpnes" << endl;
        return 1;
    }

    map<string,int> innlestekarakterer;
    ifstream infile("karakter.txt");
    if(infile.is_open()) {
        string linje;
        while(getline(infile, linje)) {
            size_t pos = linje.find(':');
            if(pos != string::npos) {
                string navn = linje.substr(0, pos);
                string karakter_str = linje.substr(pos + 1);
                int karakter = stoi(karakter_str);
                innlestekarakterer[navn] = karakter;
            }
        }
        infile.close();

        cout << "Innhold fra fil:\n";
        for(const auto& par : innlestekarakterer)
            cout << par.first << " : " << par.second << endl;
    }

    return 0;
}


#include <iostream>
#include <windows.h>
#include <cmath>
#include <iomanip>

using namespace std;

HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
COORD CursorPosition;

void gotoxy(int x, int y);

int main() {
    char userInput = 'y';

    while (userInput == 'y' || userInput == 'Y') {
        float a, b, c, A, s;
        int xPOS, yPOS;

        system("cls"); // clear screen each run

        cout << "Name: AL WILKINS BURGOS" << endl;
        cout << "BCE 315L (420)" << endl;
        cout << "CP4 - CALCULATING AREA OF A TRIANGLE" << endl << endl;

        // Draw a right triangle pattern
        xPOS = 8;
        yPOS = 5;
        for (int i = 1; i <= 10; i++) {
            gotoxy(xPOS, yPOS);
            for (int j = 1; j <= i; j++) {
                cout << "*";
            }
            yPOS++;
        }

        // Input values
        gotoxy(4, 11);
        cin >> a;

        gotoxy(12, 16);
        cin >> b;

        gotoxy(17, 10);
        cin >> c;

        // Check triangle validity
        if ((a + b <= c) || (a + c <= b) || (b + c <= a)) {
            gotoxy(0, 16);
            cout << "NOTE: The sum of any two sides must be greater than the third side." << endl;
            cout << "\nDo you want to create a new calculation? (y/n): ";
            cin >> userInput;

            if (userInput != 'y' && userInput != 'Y' && userInput != 'n' && userInput != 'N') {
                cout << "Invalid input. Exiting program." << endl;
                break;
            }
            continue; // restart loop
        }

        // Heron's formula
        s = (a + b + c) / 2.0f;
        A = sqrt(s * (s - a) * (s - b) * (s - c));

        // Results table
        gotoxy(30, 5);
        cout << "+----------+----------+----------+";
        gotoxy(30, 6);
        cout << "|            RESULTS             |";
        gotoxy(30, 7);
        cout << "+----------+----------+----------+";
        gotoxy(30, 8);
        cout << "|     A    |     B    |     C    |";
        gotoxy(30, 9);
        cout << "+----------+----------+----------+";
        gotoxy(30, 10);
        cout << "| " << setw(8) << fixed << setprecision(2) << a
             << " | " << setw(6) << b
             << "   | " << setw(6) << c << "   |";
        gotoxy(30, 11);
        cout << "+----------+----------+----------+";
        gotoxy(30, 12);
        cout << "|                                |";
        gotoxy(30, 13);
        cout << "|          AREA = " << fixed << setprecision(3) << setw(5) << A << "          |";
        gotoxy(30, 14);
        cout << "|                                |";
        gotoxy(30, 15);
        cout << "+----------+----------+----------+";

        // Repeat?
        gotoxy(0, 18);
        cout << "\nDo you want to create a new calculation? (y/n): ";
        cin >> userInput;

        if (userInput != 'y' && userInput != 'Y' && userInput != 'n' && userInput != 'N') {
            cout << "Invalid input. Exiting program." << endl;
            break;
        }
    }

    gotoxy(0, 22);
    system("pause");
}

void gotoxy(int x, int y) {
    CursorPosition.X = x;
    CursorPosition.Y = y;
    SetConsoleCursorPosition(console, CursorPosition);
}


////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#define GLAD_VULKAN_IMPLEMENTATION
#include <vulkan.h>

// Include graphics because we use sf::Image for loading images
#include <SFML/Graphics.hpp>

#include <SFML/Window.hpp>

#include <algorithm>
#include <array>
#include <iostream>
#include <limits>
#include <string_view>
#include <vector>

#include <cmath>
#include <cstdint>
#include <cstring>

////////////////////////////////////////////////////////////
// Helper functions
////////////////////////////////////////////////////////////
namespace
{
using Matrix = std::array<std::array<float, 4>, 4>;

// Multiply 2 matrices
void matrixMultiply(Matrix& result, const Matrix& left, const Matrix& right)
{
    Matrix temp;

    for (std::size_t i = 0; i < temp.size(); ++i)
    {
        for (std::size_t j = 0; j < temp[0].size(); ++j)
            temp[i][j] = left[0][j] * right[i][0] + left[1][j] * right[i][1] + left[2][j] * right[i][2] +
                         left[3][j] * right[i][3];
    }

    result = temp;
}

// Rotate a matrix around the x-axis
void matrixRotateX(Matrix& result, sf::Angle angle)
{
    const float rad = angle.asRadians();

    // clang-format off
    const Matrix matrix = {{
        {1.f,   0.f,           0.f,           0.f},
        {0.f,   std::cos(rad), std::sin(rad), 0.f},
        {0.f,  -std::sin(rad), std::cos(rad), 0.f},
        {0.f,   0.f,           0.f,           1.f}
    }};
    // clang-format on

    matrixMultiply(result, result, matrix);
}

// Rotate a matrix around the y-axis
void matrixRotateY(Matrix& result, sf::Angle angle)
{
    const float rad = angle.asRadians();

    // clang-format off
    const Matrix matrix = {{
        { std::cos(rad), 0.f, std::sin(rad), 0.f},
        { 0.f,           1.f, 0.f,           0.f},
        {-std::sin(rad), 0.f, std::cos(rad), 0.f},
        { 0.f,           0.f, 0.f,           1.f}
    }};
    // clang-format on

    matrixMultiply(result, result, matrix);
}

// Rotate a matrix around the z-axis
void matrixRotateZ(Matrix& result, sf::Angle angle)
{
    const float rad = angle.asRadians();

    // clang-format off
    const Matrix matrix = {{
        { std::cos(rad), std::sin(rad), 0.f, 0.f},
        {-std::sin(rad), std::cos(rad), 0.f, 0.f},
        { 0.f,           0.f,           1.f, 0.f},
        { 0.f,           0.f,           0.f, 1.f}
    }};
    // clang-format on

    matrixMultiply(result, result, matrix);
}

// Construct a lookat view matrix
void matrixLookAt(Matrix& result, const sf::Vector3f& eye, const sf::Vector3f& center, const sf::Vector3f& up)
{
    // Forward-looking vector
    const sf::Vector3f forward = (center - eye).normalized();

    // Side vector (Forward cross product Up)
    const sf::Vector3f side = forward.cross(up).normalized();

    result[0][0] = side.x;
    result[0][1] = side.y * forward.z - side.z * forward.y;
    result[0][2] = -forward.x;
    result[0][3] = 0.f;

    result[1][0] = side.y;
    result[1][1] = side.z * forward.x - side.x * forward.z;
    result[1][2] = -forward.y;
    result[1][3] = 0.f;

    result[2][0] = side.z;
    result[2][1] = side.x * forward.y - side.y * forward.x;
    result[2][2] = -forward.z;
    result[2][3] = 0.f;

    result[3][0] = (-eye.x) * result[0][0] + (-eye.y) * result[1][0] + (-eye.z) * result[2][0];
    result[3][1] = (-eye.x) * result[0][1] + (-eye.y) * result[1][1] + (-eye.z) * result[2][1];
    result[3][2] = (-eye.x) * result[0][2] + (-eye.y) * result[1][2] + (-eye.z) * result[2][2];
    result[3][3] = (-eye.x) * result[0][3] + (-eye.y) * result[1][3] + (-eye.z) * result[2][3] + 1.0f;
}

// Construct a perspective projection matrix
void matrixPerspective(Matrix& result, sf::Angle fov, float aspect, float nearPlane, float farPlane)
{
    const float a = 1.f / std::tan(fov.asRadians() / 2.f);

    result[0][0] = a / aspect;
    result[0][1] = 0.f;
    result[0][2] = 0.f;
    result[0][3] = 0.f;

    result[1][0] = 0.f;
    result[1][1] = -a;
    result[1][2] = 0.f;
    result[1][3] = 0.f;

    result[2][0] = 0.f;
    result[2][1] = 0.f;
    result[2][2] = -((farPlane + nearPlane) / (farPlane - nearPlane));
    result[2][3] = -1.f;

    result[3][0] = 0.f;
    result[3][1] = 0.f;
    result[3][2] = -((2.f * farPlane * nearPlane) / (farPlane - nearPlane));
    result[3][3] = 0.f;
}

// Helper function we pass to GLAD to load Vulkan functions via SFML
GLADapiproc getVulkanFunction(const char* name)
{
    return sf::Vulkan::getFunction(name);
}

// Debug we pass to Vulkan to call when it detects warnings or errors
VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
    VkDebugReportFlagsEXT,
    VkDebugReportObjectTypeEXT,
    std::uint64_t,
    std::size_t,
    std::int32_t,
    const char*,
    const char* pMessage,
    void*)
{
    std::cerr << pMessage << std::endl;

    return VK_FALSE;
}
} // namespace

////////////////////////////////////////////////////////////
// VulkanExa


#include <iostream>
#include "connection.h"
#include "CommonConnectionPool.h"
int main()
{
	/*
	测试connection的功能实现

	Connection conn;
	char sql[1024] = { 0 };
	sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')","zhangsan",20,"male");
	conn.connect("127.0.0.1", 3306, "root", "123456", "chat");
	conn.update(sql);
	*/

#if 0
	clock_t begin = clock();
	for (int i = 0;i < 10000;++i)
	{
		Connection conn;
		char sql[1024] = { 0 };
		sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
		conn.connect("127.0.0.1", 3306, "root", "123456", "chat");
		conn.update(sql);
	}
	clock_t end = clock();
	std::cout << (end - begin) << "ms" << std::endl;
	/*1000：5217ms*/
	/*5000：27932ms*/
	/*10000：55293ms*/

	clock_t begin = clock();
	ConnectionPool* cp = ConnectionPool::getConnectionPool();
	for (int i = 0;i < 5000;++i)
	{
		std::shared_ptr<Connection> sp=cp->getConnection();
		char sql[1024] = { 0 };
		sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
		sp->update(sql);
	}
	clock_t end = clock();
	std::cout << (end - begin) << "ms" << std::endl;

	/*1000：3412ms*/
	/*5000：16225ms*/
	/*10000：31749ms*/
#endif
#if 0
	clock_t begin = clock();
	ConnectionPool* cp = ConnectionPool::getConnectionPool();
	std::thread t1([&]() {
		for (int i = 0;i < 2500;++i)
		{
			std::shared_ptr<Connection> sp = cp->getConnection();
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			sp->update(sql);
		}
		});
	std::thread t2([&]() {
		for (int i = 0;i < 2500;++i)
		{
			std::shared_ptr<Connection> sp = cp->getConnection();
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			sp->update(sql);
		}
		});
	std::thread t3([&]() {
		for (int i = 0;i < 2500;++i)
		{
			std::shared_ptr<Connection> sp = cp->getConnection();
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			sp->update(sql);
		}
		});
	std::thread t4([&]() {
		for (int i = 0;i < 2500;++i)
		{
			std::shared_ptr<Connection> sp = cp->getConnection();
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			sp->update(sql);
		}
		});
	t1.join();
	t2.join();
	t3.join();
	t4.join();
	clock_t end = clock();
	std::cout << (end - begin) << "ms" << std::endl;
	/*1000：2208ms*/
	/*5000：10748ms*/
	/*10000：20639ms*/
#endif
	Connection conn;
	clock_t begin = clock();
	conn.connect("127.0.0.1", 3306, "root", "123456", "chat");
	std::thread t1([&]() {
		for (int i = 0;i < 2500;++i)
		{
			Connection conn;
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			conn.connect("127.0.0.1", 3306, "root", "123456", "chat");
			conn.update(sql);
		}
		});
	std::thread t2([&]() {
		for (int i = 0;i < 2500;++i)
		{
			Connection conn;
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			conn.connect("127.0.0.1", 3306, "root", "123456", "chat");
			conn.update(sql);
		}
		});
	std::thread t3([&]() {
		for (int i = 0;i < 2500;++i)
		{
			Connection conn;
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			conn.connect("127.0.0.1", 3306, "root", "123456", "chat");
			conn.update(sql);
		}
		});
	std::thread t4([&]() {
		for (int i = 0;i < 2500;++i)
		{
			Connection conn;
			char sql[1024] = { 0 };
			sprintf(sql, "insert into user(name,age,sex) values('%s',%d,'%s')", "zhangsan", 20, "male");
			conn.connect("127.0.0.1", 3306, "root", "123456", "chat");
			conn.update(sql);
		}
		});
	t1.join();
	t2.join();
	t3.join();
	t4.join();
	clock_t end = clock();
	std::cout << (end - begin) << "ms" << std::endl;
	return 0;
	/*1000：2297ms*/
	/*5000：11222ms*/
	/*10000：22342ms*/
}


#include <Windows.h>
#include <string>
#include <sstream>

#define ID_BTN_ENABLE   101
#define ID_BTN_DISABLE  102
#define ID_BTN_STATUS   103
#define ID_STATIC_STATUS 104

// 全局控件句柄
HWND hStatus = nullptr;
HWND hBtnEnable = nullptr;
HWND hBtnDisable = nullptr;
HWND hBtnStatus = nullptr;

// 查询 HPET 状态函数（返回 "已开启" 或 "已关闭"）
std::wstring GetHPETStatus() {
    FILE* pipe = _popen("bcdedit /enum | findstr useplatformclock", "r");
    if (!pipe) return L"无法获取状态";

    wchar_t buffer[128];
    std::wstring result;
    while (fgetws(buffer, 128, pipe)) {
        result += buffer;
    }
    _pclose(pipe);

    if (result.find(L"Yes") != std::wstring::npos)
        return L"HPET 已开启";
    else if (result.find(L"No") != std::wstring::npos)
        return L"HPET 已关闭";
    else
        return L"未知状态";
}

// 窗口过程
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_CREATE: {

            // 字体
            HFONT hFont = CreateFontW(20, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
            DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
            DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"微软雅黑");

            // 开启按钮
            hBtnEnable = CreateWindowW(L"BUTTON", L"开启 HPET",
                WS_VISIBLE | WS_CHILD,
                50, 50, 120, 40,
                hwnd, (HMENU)ID_BTN_ENABLE,
                (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
                nullptr);
            SendMessageW(hBtnEnable, WM_SETFONT, (WPARAM)hFont, TRUE);

            // 关闭按钮
            hBtnDisable = CreateWindowW(L"BUTTON", L"关闭 HPET",
                WS_VISIBLE | WS_CHILD,
                200, 50, 120, 40,
                hwnd, (HMENU)ID_BTN_DISABLE,
                (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
                nullptr);
            SendMessageW(hBtnDisable, WM_SETFONT, (WPARAM)hFont, TRUE);

            // 查看状态按钮
            hBtnStatus = CreateWindowW(L"BUTTON", L"查看状态",
                WS_VISIBLE | WS_CHILD,
                350, 50, 120, 40,
                hwnd, (HMENU)ID_BTN_STATUS,
                (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
                nullptr);
            SendMessageW(hBtnStatus, WM_SETFONT, (WPARAM)hFont, TRUE);

            // 状态显示文本
            hStatus = CreateWindowW(L"STATIC", L"当前状态: 未操作",
                WS_VISIBLE | WS_CHILD | SS_LEFT,
                50, 120, 420, 30,
                hwnd, (HMENU)ID_STATIC_STATUS,
                (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
                nullptr);
            SendMessageW(hStatus, WM_SETFONT, (WPARAM)hFont, TRUE);

            break;
        }

        case WM_CTLCOLORSTATIC: {
            HDC hdcStatic = (HDC)wParam;
            SetTextColor(hdcStatic, RGB(0, 120, 215));       // 深蓝文字
            SetBkColor(hdcStatic, RGB(204, 204, 204));       // 浅灰背景
            static HBRUSH hBrush = CreateSolidBrush(RGB(204, 204, 204));
            return (INT_PTR)hBrush;
        }

        case WM_COMMAND: {
            if (LOWORD(wParam) == ID_BTN_ENABLE) {
                int ret = system("bcdedit /set useplatformclock yes");
                std::wstring msg = (ret == 0) ? L"HPET 已开启" : L"开启 HPET 失败";
                SetWindowTextW(hStatus, msg.c_str());
            }
            else if (LOWORD(wParam) == ID_BTN_DISABLE) {
                int ret = system("bcdedit /set useplatformclock no");
                std::wstring msg = (ret == 0) ? L"HPET 已关闭" : L"关闭 HPET 失败";
                SetWindowTextW(hStatus, msg.c_str());
            }
            else if (LOWORD(wParam) == ID_BTN_STATUS) {
                std::wstring status = L"当前状态: " + GetHPETStatus();
                SetWindowTextW(hStatus, status.c_str());
            }
            break;
        }

        case WM_DESTROY: {
            PostQuitMessage(0);
            break;
        }
    }

    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSW myClass = { 0 };
    myClass.lpszClassName = L"HPETControllerWindow";
    myClass.lpfnWndProc = WindowProc;
    myClass.hIcon = (HICON)LoadImageW(NULL, L"HPET.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
    myClass.hInstance = hInstance;
    myClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

    RegisterClassW(&myClass);

    HWND hwnd = CreateWindowW(
        myClass.lpszClassName,
        L"HPET 控制器",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 540, 250,
        NULL, NULL, hInstance, NULL
    );

    ShowWindow(hwnd, nCmdShow);

    MSG msg = { 0 };
    while (GetMessageW(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    return (int)msg.wParam;
}


// ************************************************************************
// * AeroHalo Test Software
// * (c) 2025 AeroHalo - Dr. Richard Day
// * Version 1.0
// * Dimmer test
// ************************************************************************

#include <Arduino.h>

const int LED_OUT = 5;   // PWM pin driving your MMBT3904 -> P-MOSFET
const int MAX_DUTY = 255;
const int MIN_DUTY = 1;

// Half-cycle = 2.5 s (up or down). Full cycle = 5.0 s
const unsigned long HALF_MS = 2500;
const unsigned long STEP_DELAY_MS = HALF_MS / MAX_DUTY; // ≈ 9 ms per step

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED_OUT, OUTPUT);

}

void loop() {
  // Ramp UP: 0 -> 255 over ~2.5 s
  digitalWrite(LED_BUILTIN, HIGH);
  for (int d = MIN_DUTY; d <= MAX_DUTY; d++) {
    analogWrite(LED_OUT, d);
    delay(STEP_DELAY_MS);
  }

  // Ramp DOWN: 255 -> 0 over ~2.5 s
  digitalWrite(LED_BUILTIN, LOW);
  for (int d = MAX_DUTY; d >= MIN_DUTY; d--) {
    analogWrite(LED_OUT, d);
    delay(STEP_DELAY_MS);
  }
}


/*\
 *
 * PPA operation utils for LovyanGFX/M5GFX
 *
 * An incomplete experiment brought to you by tobozo, copyleft (c+) Aug. 2025
 *
\*/
#include "LGFX_PPA.hpp"

#if defined SOC_MIPI_DSI_SUPPORTED && defined CONFIG_IDF_TARGET_ESP32P4

  namespace lgfx
  {

    // ---------------------------------------------------------------------------------------------

    void* heap_alloc_ppa(size_t length, size_t*size)
    {
      size_t cache_line_size;
      if(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &cache_line_size)!=ESP_OK)
        return nullptr;
      assert(cache_line_size>=2);
      auto mask = cache_line_size-1;
      size_t aligned = (length + mask) & ~mask;
      auto ret = heap_caps_aligned_calloc(cache_line_size, 1, aligned, MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA);
      if( size ) {
        if( ret )
          *size = aligned;
        else
          *size = 0;
      }
      return ret;
    }

    // ---------------------------------------------------------------------------------------------

    // on_trans_done callback when using a semaphore
    bool IRAM_ATTR lgfx_ppa_cb_sem_func(ppa_client_handle_t ppa_client, ppa_event_data_t *event_data, void *user_data)
    {
      if( user_data ) {
        auto ppa_emitter = (PPABase*)user_data;
        ppa_emitter->setTransferDone(true);
        auto sem = ppa_emitter->getSemaphore();
        if( sem ) {
          BaseType_t xHigherPriorityTaskWoken = pdFALSE;
          xSemaphoreGiveFromISR(sem, &xHigherPriorityTaskWoken);
          return (xHigherPriorityTaskWoken == pdTRUE);
        }
      }
      ESP_LOGE(PPA_TAG, "ppa callback triggered without semaphore");
      return false;
    }

    // on_trans_done callback when *not* using a semaphore
    bool lgfx_ppa_cb_bool_func(ppa_client_handle_t ppa_client, ppa_event_data_t *event_data, void *user_data)
    {
      if( user_data ) {
        auto ppa_emitter = (PPABase*)user_data;
        ppa_emitter->setTransferDone(true);
      }
      return false;
    }

    // ---------------------------------------------------------------------------------------------

    // a little debug helper
    const char* ppa_operation_type_to_string( ppa_operation_t oper_type )
    {
      static constexpr const char* srm     = "srm";
      static constexpr const char* blend   = "blend";
      static constexpr const char* fill    = "fill";
      static constexpr const char* unknown = "unknown";
      switch(oper_type)
      {
        case PPA_OPERATION_BLEND: return blend; break;
        case PPA_OPERATION_SRM:   return srm;   break;
        case PPA_OPERATION_FILL:  return fill;  break;
        default:break;
      }
      return unknown;
    }

    // ---------------------------------------------------------------------------------------------

    ppa_fill_color_mode_t ppa_fill_color_mode(uint8_t lgfx_color_bit_depth)
    {
      if( lgfx_color_bit_depth==16 )
        return PPA_FILL_COLOR_MODE_RGB565;
      if( lgfx_color_bit_depth==24 )
        return PPA_FILL_COLOR_MODE_RGB888;
      if( lgfx_color_bit_depth==32 )
        return PPA_FILL_COLOR_MODE_ARGB8888;
      return PPA_FILL_COLOR_MODE_RGB565;
    }

    ppa_blend_color_mode_t ppa_blend_color_mode(uint8_t lgfx_color_bit_depth)
    {
      if( lgfx_color_bit_depth==16 )
        return PPA_BLEND_COLOR_MODE_RGB565;
      if( lgfx_color_bit_depth==24 )
        return PPA_BLEND_COLOR_MODE_RGB888;
      if( lgfx_color_bit_depth==32 )
        return PPA_BLEND_COLOR_MODE_ARGB8888;
      return PPA_BLEND_COLOR_MODE_RGB565;
    }

    ppa_srm_color_mode_t ppa_srm_color_mode(uint8_t lgfx_color_bit_depth)
    {
      if( lgfx_color_bit_depth==16 )
        return PPA_SRM_COLOR_MODE_RGB565;
      if( lgfx_color_bit_depth==24 )
        return PPA_SRM_COLOR_MODE_RGB888;
      if( lgfx_color_bit_depth==32 )
        return PPA_SRM_COLOR_MODE_ARGB8888;
      return PPA_SRM_COLOR_MODE_RGB565;
    }

    // ---------------------------------------------------------------------------------------------

    ppa_srm_rotation_angle_t ppa_srm_get_rotation_from_angle(float angle)
    {
      int rotation = fmod(angle, 360.0) / 90; // only 4 angles supported
      switch(rotation)
      {
        case 0: return PPA_SRM_ROTATION_ANGLE_0;
        case 1: return PPA_SRM_ROTATION_ANGLE_90;
        case 2: return PPA_SRM_ROTATION_ANGLE_180;
        case 3: return PPA_SRM_ROTATION_ANGLE_270;
      }
      return PPA_SRM_ROTATION_ANGLE_0;
    }

    float ppa_srm_get_angle_from_rotation(ppa_srm_rotation_angle_t rotation)
    {
      switch(rotation)
      {
        case PPA_SRM_ROTATION_ANGLE_0  : return 0  ;
        case PPA_SRM_ROTATION_ANGLE_90 : return 90 ;
        case PPA_SRM_ROTATION_ANGLE_180: return 180;
        case PPA_SRM_ROTATION_ANGLE_270: return 270;
      }
      return 0;
    }

    // ---------------------------------------------------------------------------------------------

    void* PPA_Sprite::createSprite(int32_t w, int32_t h)
    {
      uint8_t b


#include "ve_pipeline.hpp"
#include "ve_model.hpp"
#include <fstream>
#include <stdexcept>
#include <iostream>
#include <cassert>
namespace ve{
LvePipeline::LvePipeline(
        LveDevice& device,
        const std::string& vertFilepath,
        const std::string& fragFilepath,
        const PipelineConfigInfo& configInfo) : lveDevice(device){
    createGraphicsPipeline(vertFilepath, fragFilepath, configInfo);
}

LvePipeline::~LvePipeline(){
    vkDestroyShaderModule(lveDevice.device(), vertShaderModule, nullptr);
    vkDestroyShaderModule(lveDevice.device(), fragShaderModule, nullptr);
    vkDestroyPipeline(lveDevice.device(), graphicsPipeline, nullptr);
}

std::vector<char> LvePipeline::readFile(const std::string& filepath){
    std::ifstream file(filepath, std::ios::ate | std::ios::binary);
    if(!file.is_open()){
        throw std::runtime_error("failed to open file: " + filepath);
    }
    size_t fileSize = static_cast<size_t>(file.tellg());
    std::vector<char> buffer(fileSize);
    file.seekg(0);
    file.read(buffer.data(), fileSize);
    file.close();
    return buffer;
}
void LvePipeline::createGraphicsPipeline(const std::string& vertFilepath, const std::string& fragFilepath, const PipelineConfigInfo& configInfo){
    assert(configInfo.pipelineLayout != VK_NULL_HANDLE && "Cannot create graphics pipeline: no pipelinelayout provided in configInfo");
    assert(configInfo.renderPass != VK_NULL_HANDLE && "Cannot create graphics pipeline: no pipelinelayout provided in configInfo");
    auto vertCode = readFile(vertFilepath);
    auto fragCode = readFile(fragFilepath);

    createShaderModule(vertCode, &vertShaderModule);
    createShaderModule(fragCode, &fragShaderModule);

    VkPipelineShaderStageCreateInfo shaderStages[2];
    shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
    shaderStages[0].module = vertShaderModule;
    shaderStages[0].pName = "main";
    shaderStages[0].flags = 0;
    shaderStages[0].pNext = nullptr;
    shaderStages[0].pSpecializationInfo = nullptr;

    shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
    shaderStages[1].module = fragShaderModule;
    shaderStages[1].pName = "main";
    shaderStages[1].flags = 0;
    shaderStages[1].pNext = nullptr;
    shaderStages[1].pSpecializationInfo = nullptr;

    auto bindingDescriptions = LveModel::Vertex::getBindingDescriptions();
    auto attributeDescriptions = LveModel::Vertex::getAttributeDescriptions();
    VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
    vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
    vertexInputInfo.vertexBindingDescriptionCount = static_cast<uint32_t>(bindingDescriptions.size());
    vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
    vertexInputInfo.pVertexBindingDescriptions = bindingDescriptions.data();

    VkGraphicsPipelineCreateInfo pipelineInfo{};
    pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    pipelineInfo.stageCount = 2;
    pipelineInfo.pStages = shaderStages;
    pipelineInfo.pVertexInputState = &vertexInputInfo;
    pipelineInfo.pInputAssemblyState = &configInfo.inputAssemblyInfo;
    pipelineInfo.pViewportState = &configInfo.viewportInfo;
    pipelineInfo.pRasterizationState = &configInfo.rasterizationInfo;
    pipelineInfo.pMultisampleState = &configInfo.multisampleInfo;
    pipelineInfo.pColorBlendState = &configInfo.colorBlendInfo;
    pipelineInfo.pDepthStencilState = &configInfo.depthStencilInfo;
    pipelineInfo.pDynamicState = &configInfo.dynamicStateInfo;

    pipelineInfo.layout = configInfo.pipelineLayout;
    pipelineInfo.renderPass = configInfo.renderPass;
    pipelineInfo.subpass = configInfo.subpass;

    pipelineInfo.basePipelineIndex = -1;
    pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;

    if(vkCreateGraphicsPipelines(lveDevice.device(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS){
        throw std::runtime_error("failed to create graphics pipeline");
    }
}
void LvePipeline::createShaderModule(const std::vector<char>& code, VkShaderModule* shaderModule){
    VkShaderModuleCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
    createInfo.codeSize = code.size();
    createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());

    if(vkCreateShaderModule(lveDevice.device(), &createInfo, nullptr, shaderModule) != VK_SUCCESS){
        throw std::runtime_error("failed to create shader module");
    }
}

void LvePipeline::bind(VkCommandBuffer commandBuffer){
    vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);

}

void LvePipeline::defaultPipelineConfigInfo(Pipeline


// test_human.cpp
#include "catch_amalgamated.hpp"
#include "human.h"
#include <sstream>

TEST_CASE("Human getAge method", "[Human]") {
    Human human("John Doe", "Engineer", 1990);
    REQUIRE(human.getAge() == 35);
}

TEST_CASE("Human introduce method", "[Human]") {
    Human human("John Doe", "Engineer", 1990);
    std::ostringstream output;
    std::streambuf* oldCoutBuffer = std::cout.rdbuf(output.rdbuf());

    human.introduce();

    std::cout.rdbuf(oldCoutBuffer);
    REQUIRE(output.str() == "I am Creature named John Doe and I have 100% of health.\n"
                            "I am a Engineer and I am 35 years old.\n");
}

TEST_CASE("Human attack method", "[Human]") {
    Human human("John Doe", "Engineer", 1990);
    Human opponent("Jane Doe", "Doctor", 1992);
    human.attack(&opponent);
    REQUIRE(opponent.getHealthPercentage() == 90);
}

TEST_CASE("Human toString method", "[Human]") {
    Human human("John Doe", "Engineer", 1990);
    REQUIRE(human.toString() == "Human(Creature(name: John Doe, health: 100, maxHealth: 100), occupation: Engineer, bornYear: 1990)");
}


#include"hound_ai.hpp"

/***************************************************************
HOUND AI CLASS DEFINITION
*/

HoundAI::HoundAI(
    unsigned id,
    unsigned agent_speed,
    std::mt19937_64* rng
)
    : AI(id, agent_speed, rng)
{
}

std::vector<std::string> HoundAI::Run(
    Percepts& percepts,
    AgentComm * comms
) {

    // DO NOT LEAVE THIS CODE (COMMENTED OUT OR IN) IN
    // YOUR SUBMISSION

    /*std::cout << "\n=========================\n";
    std::cout << "HOUND ID: " << id << std::endl;
    std::cout << "CURRENT: ";
    for (size_t i = 0; i < percepts.current.size(); i++) {
        std::cout << percepts.current[i] << " ";
    }
    std::cout << "\nFORWARD: ";
    for (size_t i = 0; i < percepts.forward.size(); i++) {
        std::cout << percepts.forward[i] << " ";
    }
    std::cout << "\nBACKWARD: ";
    for (size_t i = 0; i < percepts.backward.size(); i++) {
        std::cout << percepts.backward[i] << " ";
    }
    std::cout << "\nLEFT: ";
    for (size_t i = 0; i < percepts.left.size(); i++) {
        std::cout << percepts.left[i] << " ";
    }
    std::cout << "\nRIGHT: ";
    for (size_t i = 0; i < percepts.right.size(); i++) {
        std::cout << percepts.right[i] << " ";
    }
    std::cout << "\nSIGHTINGS:\n";
    for (size_t i = 0; i < percepts.sightings.size(); i++) {
        if (percepts.sightings[i].type == AgentType::FOX) std::cout << "   FOX ";
        else std::cout << "  HOUND ";
        std::cout << "Dir " << percepts.sightings[i].direction << " ";
        std::cout << "Dis " << percepts.sightings[i].distance << "\n";
    }
    std::cout << "SCENT: " << percepts.scent << std::endl;*/
    std::cout << "COMMS:\n";
    if (comms == nullptr) std::cout << "No communication.\n";
    else {
        for (size_t i = 0; i < comms->bark.size(); i++) {
            std::cout << "HOUND " << i << " Bark: " << comms->bark[i]
                << " Dir: " << comms->direction[i].to_string()
                << std::endl;
        }
    }

    /***************************************************************
    YOUR HOUND AI CODE GOES HERE.
    Notes:
    - you may add other member functions to this class.
    - you may add member data to this class.
    - you may develop new classes to help or supplement this one.
    - you may NOT alter the function definition here or where
        it is called by the simulation.
    - you may not alter ANY simulation code other than this AI file.
    */

    // The following is a purely random solution to give you an idea
    // how percepts and commands work. You should not include the
    // following in your solution.

    // If the AI's id is 0, it sets its message to 9.
    // This demonstrates how you can pass messages.
    if (id == 0) {
        comms->bark[0] = 9;
    }

    std::vector<std::string> cmds;

    std::vector<std::string> arr = { "F", "L", "R" };

    for (unsigned i = 0; i < agent_speed; i++) {
        std::shuffle(arr.begin(), arr.end(), *rng);
        cmds.push_back(arr[0]);
    }
    return cmds;
}


/*
 *      Interactive disassembler (IDA)
 *      Copyright (c) 1990-98 by Ilfak Guilfanov.
 *                        E-mail: ig@datarescue.com
 *      RT11 executable Loader.
 *      Copyright (c) 1995-2006 by Iouri Kharon.
 *                        E-mail: yjh@styx.cabel.net
 *
 *      ALL RIGHTS RESERVED.
 *
 */

/*
        L O A D E R  for RT11 .sav-files
*/

#include "../idaldr.h"
#include "../../module/pdp11/pdp_ml.h"

//--------------------------------------------------------------------------
//
//      check input file format. if recognized, then return 1
//      and fill 'fileformatname'.
//      otherwise return 0
//
static int idaapi accept_file(
        qstring *fileformatname,
        qstring *processor,
        linput_t *li,
        const char *filename)
{
  uint64 fsize = qlsize(li);

  if ( (fsize % 512) || !fsize )
    return 0;
  qlseek(li, 040);

  ushort tmp;
  lread2bytes(li, &tmp, 0);
  if ( tmp > fsize || (tmp & 1) || tmp < 0400 )
    return 0;
  lread2bytes(li, &tmp, 0);
  if ( tmp > fsize )
    return 0;
  qlseek(li, 050);
  lread2bytes(li, &tmp, 0);
  if ( tmp & 1 || tmp > fsize )
    return 0;

// 20.11.01, ig
// got tired of too many false positives
// now we'll check the file extension

  const char *ext = get_file_ext(filename);
  if ( ext == nullptr || stricmp(ext, "sav") != 0 )
    return 0;

  *fileformatname = "RT11 (pdp11) sav-file";
  *processor      = "pdp11";
  return f_LOADER;
}

//--------------------------------------------------------------------------
static void loadchunk(
        linput_t *li,
        ea_t ea,
        size_t size,
        ea_t base,
        int32 fpos,
        const char *sclass)
{
  qoff64_t p = qltell(li);
  file2base(li, fpos, ea, ea+size, FILEREG_PATCHABLE);
  add_segm(base, ea, ea+size, nullptr, sclass);
  qlseek(li, p);
}

//--------------------------------------------------------------------------
//
//      load file into the database.
//

void idaapi load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/)
{
  set_processor_type("pdp11", SETPROC_LOADER);

  pdp_ml_t *ml = nullptr;
  netnode  *ml_ovrtrans = nullptr;
  if ( !pdp11_module_t::get_ml_ptr(&ml, &ml_ovrtrans)
    || !ml
    || !ml_ovrtrans )
  {
    error("Internal error in loader<->module link");
  }
//
//  Find out asect section and load it
//
  int i;
  segment_t s;
  s.start_ea = to_ea(inf_get_baseaddr(), 0);
  qlseek(li, 040);
  ushort startIP, topPrg, svrEnd, ovt;
  lread(li, &startIP, sizeof(ushort));
  lread(li, &ml->asect_top, sizeof(ushort));
  if ( (startIP & 1) || startIP < 0400 )
    startIP = 0;
  else
    inf_set_start_ip(startIP);
  qlseek(li, 050);
  lread(li, &topPrg, sizeof(ushort));
  if ( topPrg & 1 || (uint64)topPrg > qlsize(li) )
    topPrg = 0;
  if ( topPrg > 01000
    && ml->asect_top < (topPrg - 01000 )
    && ml->asect_top > 0400 )
  {
    svrEnd = ml->asect_top;
    if ( ml->asect_top > 01000 )
      svrEnd = 01000;
  }
  else
  {
    ml->asect_top = svrEnd = 01000;
  }
  if ( startIP && ml->asect_top > startIP )
  {
    svrEnd = 01000;
    if ( svrEnd > startIP )
      svrEnd = startIP;
    s.end_ea = s.start_ea + svrEnd;
  }
  else
  {
    s.end_ea = s.start_ea + ml->asect_top;
  }
  inf_set_start_cs(inf_get_baseaddr());
  file2base(li, 0, s.start_ea, s.end_ea, FILEREG_PATCHABLE);
  s.type = SEG_IMEM;
  s.sel  = find_selector(inf_get_baseaddr());
  add_segm_ex(&s, "asect", nullptr, ADDSEG_NOSREG);

  if ( inf_get_start_ip() != BADADDR )
    op_plain_offset(s.start_ea + 040, 0, s.start_ea);
  else
    create_word(s.start_ea + 040, 2);
  create_word(s.start_ea + 042, 2);  // begin stack value
  create_word(s.start_ea + 044, 2);  // JSW
  create_word(s.start_ea + 046, 2);  // load USR address
  create_word(s.start_ea + 050, 2);  // top programm loading address

  ushort begovrtbl = get_word(s.start_ea + 064);
  ea_t ei;
  for ( ei = s.start_ea; ei < s.start_ea + 040; ei += 2 )
  {
    if ( get_word(ei) )
    {
      create_word(ei, 2);
    }
    else
    {
      del_value(ei);
      del_value(ei+1);
    }
  }
  for ( ei = s.start_ea + 052; ei < s.end_ea; ei += 2 )
  {
    if ( get_word(ei) )
    {
      create_word(ei, 2);
    }
    else
    {
      del_value(ei);
      del_value(ei+1);
    }
  }

  ovt = ml->asect_top;
  if ( s.end_ea != (s.start_ea + ml->asect_top) )
  {
    loadchunk(li, s.end_ea, ml->asect_top - svrEnd, inf_get_baseaddr(), svrEnd, "USER");
    s.end_ea += (ml->asect_top - svrEnd);
    ml->asect_top = svrEnd;
  }

  if ( get_word(s.start_ea + 044) & 01000 )
  {
    if ( begovrtbl == 0 )
    {
      static const ushort chkold[] = { 010046, 010146, 010246, 0421, 010001, 062701 };
      qlseek(li, ovt);
      ushort temp;
      for ( i = 0; i < sizeof(chkold)/2; i++ )
      {
        lread(li, &temp, sizeof(ushort));
        if ( temp != chkold[i] )
          goto nons;
      }
      lread(li, &temp, sizeof(ushort));
      if ( temp != ovt + 076 )
        goto nons;
      qlseek(li, ovt + 0100);
      lread(li, &te


/*#include <iostream>

void mundo() {
    std::cout << "Hello World!\n";
}

int sumar(int n1, int n2) {
    int suma = 0;
    suma = n1 + n2;
    return suma;
}

int main()
{
    int a, b;
    mundo();
    mundo();
    mundo();
    mundo();
    printf("Escribe 2 numeros para la suma\n");
    scanf_s("%i %i", &a, &b);

    printf("La suma es %i", sumar(a,b));
    return 0;
}*/

/*#include<iostream>
using namespace std;

int sum(int a = 7, int b = 5) {
    return a + b;
}

float sum(float a, float b) {
    return a + b;
}

double sum(double a, double b) {
    return a + b;
}

double sum(int a, double b) {
    return a + b;
}

//template<class T>
template<typename T, typename R>
T sum(T a, R b) {
    return a + b;
}

void main() {
    //cout << sum(1) << endl;
    cout << sum(10.9f,5.3f) << endl;
    cout << sum(10, 7) << endl;
    cout << sum(9.8, 1.2) << endl;
    cout << sum(5, 8.2);
}*/
/*#include <iostream>
using namespace std;

void cambio(int a,int b) {
	cout  << a << " " << b << endl;
	int temp = a;
	a = b;
	b = temp;
	cout << a << " " << b << endl;
}

void main() {
	int a = 10, b = 20;
	cambio(a, b);
	cout << a << " " << b << endl;
}*/

/*#include <iostream>
using namespace std;

int g = 5;

void fun(){
    int a = 10;
	a++;
	g++;
	cout << a << " " << g << endl;
}

void main() {
	cout << g <<endl;
    fun();
	cout << g <<endl;
}*/

/*#include <iostream>
using namespace std;

int x = 10;
void main() {
    int x = 20;
    {
		int x = 30;
		cout << x << endl;
    }
	cout << x << endl;
	cout << ::x << endl;
}*/

/*#include<iostream>
using namespace std;

void fun() {
    int s = 10;
    s++;
    cout << s << endl;
}

int main() {
    fun();
    fun();
    fun();
    return 0;
}*/

/*#include<iostream>
using namespace std;

void fun(int n) {
    if (n > 0) {
        cout << n << endl;
        fun(n - 1);
        cout << n << endl;
    }
}

int main() {
    int x = 5;
    fun(x);
    return 0;
}*/

/*
    Funciones Matematicas:
ceil(x) -> Redondea al entero mayor mas cercano
fabs(x) -> Devuelve el valor absoluto de x
floor(x) -> Redondea al entero menor mas cercano
sqrt(x) -> Saca la raiz cuadrada de x
fmod(x,y) -> Calcula el resto de la division de x/y
pow(x,y) -> Calcula x elevado a la potencia y
*/

/*#include <stdio.h>
#include <math.h>

void funcionMate();

int main() {

    funcionMate();
    return 0;
}

void funcionMate() {

    float x, y, cambio = 0;

    printf("Escribe dos numeros:\n");
    scanf_s("%f %f", &x, &y);

    cambio = pow(x, y); //Redondea al siguiente numero entero 2.1 -> 3
    printf("%.2f", cambio);
}*/

/*
    Funciones Trigonometricas

        (Si requiere la libreria math.h)

acos(x) -> Calcula el Arco Coseno de x
asin(x) -> Calcula el Arco Seno de x
atan(x) -> Calcula el Arco Tangente de x
cos(x) -> Calcula el Coseno de x
sin(x) -> Calcula el Seno de x
tan(x) -> Calcula la Tangente de x
*/
/*#include <stdio.h>
#include <math.h>

void funcionTrigonometrica() {

    float x, cambio = 0;
    printf("Escribe un numero\n");
    scanf_s("%f", &x);

    cambio = asin(x);
    printf("El resultado es %f", cambio);

}

int main() {
    funcionTrigonometrica();
    return 0;
}*/


#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>

#include "flutter_window.h"
#include "utils.h"

int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
                      _In_ wchar_t *command_line, _In_ int show_command) {
  // Attach to console when present (e.g., 'flutter run') or create a
  // new console when running with a debugger.
  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
    CreateAndAttachConsole();
  }

  // Initialize COM, so that it is available for use in the library and/or
  // plugins.
  ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

  flutter::DartProject project(L"data");

  std::vector<std::string> command_line_arguments =
      GetCommandLineArguments();

  project.set_dart_entrypoint_arguments(std::move(command_line_arguments));

  FlutterWindow window(project);
  Win32Window::Point origin(10, 10);
  Win32Window::Size size(1280, 720);
  if (!window.Create(L"signin", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


#include "headers/stdafx.h"
#include "headers/Rect.h"

Rect::Rect() : ptLT_(0.0, 0.0), ptRB_(0.0, 0.0) {}
Rect::Rect(const Rect& other){ // конструктор копирования
	ptLT_ = other.ptLT_;
	ptRB_ = other.ptRB_;
}
Rect::Rect(double left, double top, double right, double bottom)
	: ptLT_(left, top), ptRB_(right, bottom) {}

Rect::Rect(const Vector& lt, const Vector& rb){
	ptLT_ = lt;
	ptRB_ = rb;

}

Rect& Rect::operator=(const Rect& other){
	if (this != &other){
		ptLT_ = other.ptLT_;
		ptRB_ = other.ptRB_;
	}
	return *this;
}

void Rect::Inflate(double value) {
	ptLT_ = ptLT_ + Vector(-value, value);
	ptRB_ = ptRB_ + Vector(value, -value);
}

void Rect::Inflate(double x_c, double y_c) {
	ptLT_ = ptLT_ + Vector(-x_c, y_c);
	ptRB_ = ptRB_ + Vector(x_c, -y_c);
}

void Rect::Inflate(double left, double top, double right, double bottom) {
	ptLT_ = ptLT_ + Vector(-left, top);
	ptRB_ = ptRB_ + Vector(right, -bottom);
}

void Rect::Out() const {
	std::cout << "\nRect: ";
	ptLT_.Out();
	ptRB_.Out();
}

void Rect::Move(Vector& v){
	ptLT_ = ptLT_ + v;
	ptRB_ = ptRB_ + v;
}

double Rect::Area() const{
	double width = fabs(ptRB_.GetX() - ptLT_.GetX());
	double height = fabs(ptRB_.GetY() - ptLT_.GetY());
	return width * height;
}


#include "pch.h"
#include "GameLogic.h"
#include "Hero.h"
#include "Enemy.h"
#include "Grid.h"
#include <queue>

bool playerTurn = true;
float timer = 0;
Rectangle attackButton;
Cell* targetCell = nullptr;

std::queue<Coroutine::StepFunc> enemyQueue;
Coroutine::StepFunc currentEnemyCoroutine = nullptr;

GameLogic& GameLogic::Instance() {
    static GameLogic instance;
    return instance;
}

void GameLogic::Update(float deltaTime)
{
    if (ActiveHero != NULL && playerTurn && ActiveHero->stamina > 0)
        ActiveHero->Update();

    SelectEntityFromCell();

    if (ActiveHero != NULL && CheckStamina()) {
        EndTurn();
    }

    if (timer <= tourTime) {
        timer += deltaTime;
        if (timer >= 30) {
            EndTurn();
        };
    }

    //enemy turn
    if (!playerTurn) {
        if (!currentEnemyCoroutine && !enemyQueue.empty()) {
            currentEnemyCoroutine = enemyQueue.front();
            enemyQueue.pop();
            timer = 0;
        }

        if (currentEnemyCoroutine) {
            bool running = currentEnemyCoroutine(deltaTime);
            if (!running) {
                currentEnemyCoroutine = nullptr;
            }
        }

        if (!currentEnemyCoroutine && enemyQueue.empty()) {
            EndTurn();
        }
    }
}

void GameLogic::Draw()
{
    Timer();
    DrawAttackButton();
    DrawEndTourButton();
}

void GameLogic::SelectEntityFromCell()
{
    if (IsMouseButtonPressed(0)) {
        Vector2 mousePos = GetMousePosition();
        int x = mousePos.x;
        int y = mousePos.y;

        if (CheckCollisionPointRec(mousePos, attackButton) && playerTurn) {
            if (IsMouseButtonPressed(0)) {
                ActiveHero->Attack(ActiveEnemy, targetCell);
            }
            return;
        }

        if (!Grid::Instance().IsInsideGrid(x, y)) return;

        Cell* c = &Grid::Instance().GetCellAtMousePos(x, y);
        Entity* entity = c->owner;

        Hero* hero = dynamic_cast<Hero*>(entity);
        Enemy* enemy = dynamic_cast<Enemy*>(entity);

        if (hero) {
            ActiveHero = hero;
            printf("Active hero set: %s\n", ActiveHero->heroName);
        }
        else if (enemy) {
            targetCell = &Grid::Instance().GetCellAtMousePos(x, y);
            ActiveEnemy = enemy;
            printf("Active enemy set: %s\n", ActiveEnemy->enemyName);
        }
        else
        {
            ActiveHero = NULL;
            ActiveEnemy = NULL;
        }
    }
}

void GameLogic::Timer() {
    Vector2 center = { screenWidth - 1600, screenHeight - 100 };
    float rotationSpeed = 12.0;
    float endAngle = fmod(timer * rotationSpeed, 360.0f);
    DrawCircleSector(center, 30, 0, endAngle, 32, RED);
}

void GameLogic::DrawAttackButton()
{
    attackButton = { screenWidth - 500, screenHeight / 2 - 25, 150, 50 };

    if (ActiveEnemy != nullptr && ActiveHero != nullptr) {
        DrawRectangleRec(attackButton, LIGHTGRAY);
        DrawText("Attack", attackButton.x + 40, attackButton.y + 10, 20, BLACK);
    }
}

void GameLogic::DrawEndTourButton()
{
    if (!playerTurn) return;
    endTurnButton = { screenWidth - 300, screenHeight - 100, 150, 50 };

    DrawRectangleRec(endTurnButton, LIGHTGRAY);
    DrawText("End Turn", endTurnButton.x + 30, endTurnButton.y + 10, 20, BLACK);

    if (IsMouseButtonPressed(0) && playerTurn) {
        Vector2 mousePos = GetMousePosition();
        if (CheckCollisionPointRec(mousePos, endTurnButton)) {
            EndTurn();
        }
    }
}

bool GameLogic::CheckStamina()
{
    for (Hero* hero : heroes) {
        if (hero->stamina > 0) {
            return false;
        }
    }
    return true;
}

void GameLogic::AddEntity(Entity* entity)
{
	if (Hero* hero = dynamic_cast<Hero*>(entity)) {
		heroes.push_back(hero);
	}
	else if (Enemy* enemy = dynamic_cast<Enemy*>(entity)) {
		enemies.push_back(enemy);
	}

	entities.push_back(entity);
}

void GameLogic::EndTurn()
{
    printf("End turn. Player turn: %s\n", playerTurn ? "true" : "false");

    for (Hero* hero : heroes) {
        if (!playerTurn) continue;
        hero->StaminaUpdate(30);
    }

    timer = 0;
    playerTurn = !playerTurn;

    if (!playerTurn) {
        while (!enemyQueue.empty()) enemyQueue.pop();
        currentEnemyCoroutine = nullptr;
        for (Enemy* enemy : enemies) {
            if (enemy->isAlive)
                enemyQueue.push(enemy->Act());
        }
    }
}


/*
*
*    This program is free software; you can redistribute it and/or modify it
*    under the terms of the GNU General Public License as published by the
*    Free Software Foundation; either version 2 of the License, or (at
*    your option) any later version.
*
*    This program is distributed in the hope that it will be useful, but
*    WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program; if not, write to the Free Software Foundation,
*    Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*    In addition, as a special exception, the author gives permission to
*    link the code of this program with the Half-Life Game Engine ("HL
*    Engine") and Modified Game Libraries ("MODs") developed by Valve,
*    L.L.C ("Valve").  You must obey the GNU General Public License in all
*    respects for all of the code used other than the HL Engine and MODs
*    from Valve.  If you modify this file, you may extend this exception
*    to your version of the file, but you are not obligated to do so.  If
*    you do not wish to do so, delete this exception statement from your
*    version.
*
*/

#include "precompiled.h"

bool CTextConsole::Init(IBaseSystem *system)
{
	// NULL or a valid base system interface
	m_System = system;

	Q_memset(m_szConsoleText, 0, sizeof(m_szConsoleText));
	m_nConsoleTextLen = 0;
	m_nCursorPosition = 0;

	Q_memset(m_szSavedConsoleText, 0, sizeof(m_szSavedConsoleText));
	m_nSavedConsoleTextLen = 0;

	Q_memset(m_aszLineBuffer, 0, sizeof(m_aszLineBuffer));
	m_nTotalLines = 0;
	m_nInputLine = 0;
	m_nBrowseLine = 0;

	// these are log messages, not related to console
	Sys_Printf("\n");
	Sys_Printf("Console initialized.\n");

	m_ConsoleVisible = true;

	return true;
}

void CTextConsole::InitSystem(IBaseSystem *system)
{
	m_System = system;
}

void CTextConsole::SetVisible(bool visible)
{
	m_ConsoleVisible = visible;
}

bool CTextConsole::IsVisible()
{
	return m_ConsoleVisible;
}

void CTextConsole::ShutDown()
{
	;
}

void CTextConsole::Print(char *pszMsg)
{
	if (m_nConsoleTextLen)
	{
		int nLen = m_nConsoleTextLen;
		while (nLen--)
		{
			PrintRaw("\b \b");
		}
	}

	PrintRaw(pszMsg);

	if (m_nConsoleTextLen)
	{
		PrintRaw(m_szConsoleText, m_nConsoleTextLen);
	}

	UpdateStatus();
}

int CTextConsole::ReceiveNewline()
{
	int nLen = 0;

	Echo("\n");

	if (m_nConsoleTextLen)
	{
		nLen = m_nConsoleTextLen;

		m_szConsoleText[ m_nConsoleTextLen ] = '\0';
		m_nConsoleTextLen = 0;
		m_nCursorPosition = 0;

		// cache line in buffer, but only if it's not a duplicate of the previous line
		if ((m_nInputLine == 0) || (Q_strcmp(m_aszLineBuffer[ m_nInputLine - 1 ], m_szConsoleText)))
		{
			Q_strncpy(m_aszLineBuffer[ m_nInputLine ], m_szConsoleText, MAX_CONSOLE_TEXTLEN);
			m_nInputLine++;

			if (m_nInputLine > m_nTotalLines)
				m_nTotalLines = m_nInputLine;

			if (m_nInputLine >= MAX_BUFFER_LINES)
				m_nInputLine = 0;

		}

		m_nBrowseLine = m_nInputLine;
	}

	return nLen;
}

void CTextConsole::ReceiveBackspace()
{
	int nCount;

	if (m_nCursorPosition == 0)
	{
		return;
	}

	m_nConsoleTextLen--;
	m_nCursorPosition--;

	Echo("\b");

	for (nCount = m_nCursorPosition; nCount < m_nConsoleTextLen; ++nCount)
	{
		m_szConsoleText[ nCount ] = m_szConsoleText[ nCount + 1 ];
		Echo(m_szConsoleText + nCount, 1);
	}

	Echo(" ");

	nCount = m_nConsoleTextLen;
	while (nCount >= m_nCursorPosition)
	{
		Echo("\b");
		nCount--;
	}

	m_nBrowseLine = m_nInputLine;
}

void CTextConsole::ReceiveTab()
{
	if (!m_System)
		return;

	ObjectList matches;
	m_szConsoleText[ m_nConsoleTextLen ] = '\0';
	m_System->GetCommandMatches(m_szConsoleText, &matches);

	if (matches.IsEmpty())
		return;

	if (matches.CountElements() == 1)
	{
		char *pszCmdName = (char *)matches.GetFirst();
		char *pszRest = pszCmdName + Q_strlen(m_szConsoleText);

		if (pszRest)
		{
			Echo(pszRest);
			Q_strlcat(m_szConsoleText, pszRest);
			m_nConsoleTextLen += Q_strlen(pszRest);

			Echo(" ");
			Q_strlcat(m_szConsoleText, " ");
			m_nConsoleTextLen++;
		}
	}
	else
	{
		int nLongestCmd = 0;
		int nSmallestCmd = 0;
		int nCurrentColumn;
		int nTotalColumns;
		char szCommonCmd[256]; // Should be enough.
		char szFormatCmd[256];
		char *pszSmallestCmd;
		char *pszCurrentCmd = (char *)matches.GetFirst();
		nSmallestCmd = Q_strlen(pszCurrentCmd);
		pszSmallestCmd = pszCurrentCmd;
		while (pszCurrentCmd)
		{
			if ((int)Q_strlen(pszCurrentCmd) > nLongestCmd)
			{
				nLongestCmd = Q_strlen(pszCurrentCmd);
			}
			if ((int)Q_strlen(pszCurrentCmd) < nSmallestCmd)
			{
				nSmallestCmd = Q_strlen(pszCurrentCmd);
				pszSmallestCmd = pszCurrentCmd;
			}
			pszCurrentCmd = (char *)matches.GetNext();
		}

		nTotalColumns = (GetWidth() - 1) / (nLongestCmd + 1);
		nCurrentColumn = 0;

		Echo("\n");
		Q_strcpy(szCommonCmd, pszSmalles


#include "plugindialog.h"
#include <QApplication>
#include <QGroupBox>
#include <QHeaderView>
#include <QScrollBar>
#include <QStandardPaths>
#include <QDir>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QProcess>
#include <QThread>
#include <QMetaObject>
#include <QInputDialog>
#include <QProgressDialog>
#include <QColor>
#include <QPainter>
#include <QStyle>

#include <QScreen>
#include <QWindow>
#include <QMimeData>
#include <QDrag>
#include <QTimer>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSslConfiguration>
#include <QCryptographicHash>
#include <QUuid>
#include <algorithm>
#include <memory>

// PluginDialog implementation
PluginDialog::PluginDialog(PluginManager* pluginManager, QWidget *parent)
    : QDialog(parent)
    , m_tabWidget(nullptr)
    , m_pluginsTree(nullptr)
    , m_loadPluginButton(nullptr)
    , m_unloadPluginButton(nullptr)
    , m_activatePluginButton(nullptr)
    , m_deactivatePluginButton(nullptr)
    , m_configurePluginButton(nullptr)
    , m_viewDetailsButton(nullptr)
    , m_storeTable(nullptr)
    , m_installPluginButton(nullptr)
    , m_uninstallPluginButton(nullptr)
    , m_updatePluginButton(nullptr)
    , m_checkUpdatesButton(nullptr)
    , m_storeProgress(nullptr)
    , m_scriptsList(nullptr)
    , m_executeScriptButton(nullptr)
    , m_addScriptButton(nullptr)
    , m_removeScriptButton(nullptr)
    , m_scriptEditor(nullptr)
    , m_rulesTable(nullptr)
    , m_addRuleButton(nullptr)
    , m_removeRuleButton(nullptr)
    , m_editRuleButton(nullptr)
    , m_loadRulesButton(nullptr)
    , m_saveRulesButton(nullptr)
    , m_generalSettingsGroup(nullptr)
    , m_autoLoadCheck(nullptr)
    , m_autoUpdateCheck(nullptr)
    , m_pluginDirectoryEdit(nullptr)
    , m_browsePluginDirButton(nullptr)
    , m_securitySettingsGroup(nullptr)
    , m_verifySignaturesCheck(nullptr)
    , m_strictValidationCheck(nullptr)
    , m_manageTrustedButton(nullptr)
    , m_performanceSettingsGroup(nullptr)
    , m_maxConcurrentPluginsSpin(nullptr)
    , m_enableCachingCheck(nullptr)
    , m_pluginDetailsEdit(nullptr)
    , m_pluginStatus(nullptr)
    , m_pluginManager(pluginManager)
    , m_scriptEngine(nullptr)
    , m_rulesManager(nullptr)
    , m_pluginValidator(nullptr)
    , m_networkManager(nullptr)
    , m_refreshTimer(new QTimer(this))
{
    setupUI();
    setupConnections();

    // Initialize components
    if (m_pluginManager) {
        m_scriptEngine = std::make_unique<ScriptEngine>(this);
        m_rulesManager = std::make_unique<CustomRulesManager>(this);
        m_pluginValidator = std::make_unique<PluginValidator>(this);
        m_networkManager = std::make_unique<QNetworkAccessManager>(this);
    }

    // Load initial data
    populatePlugins();
    populatePluginStore();
    populateCustomRules();

    setWindowTitle(tr("Plugin Manager"));
    setMinimumSize(900, 700);
    resize(1000, 800);
}

PluginDialog::~PluginDialog() {
}

void PluginDialog::setupUI() {
    QVBoxLayout* mainLayout = new QVBoxLayout(this);

    // Create tab widget
    m_tabWidget = new QTabWidget();

    // Plugins tab
    QWidget* pluginsTab = new QWidget();
    QVBoxLayout* pluginsLayout = new QVBoxLayout(pluginsTab);

    // Plugins tree
    m_pluginsTree = new QTreeWidget();
    m_pluginsTree->setHeaderLabels(QStringList() << tr("Name") << tr("Version") << tr("Status") << tr("Type"));
    m_pluginsTree->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_pluginsTree->setSelectionMode(QAbstractItemView::SingleSelection);
    m_pluginsTree->setAlternatingRowColors(true);

    // Plugin buttons
    QHBoxLayout* pluginButtonLayout = new QHBoxLayout();
    m_loadPluginButton = new QPushButton(tr("Load"));
    m_unloadPluginButton = new QPushButton(tr("Unload"));
    m_activatePluginButton = new QPushButton(tr("Activate"));
    m_deactivatePluginButton = new QPushButton(tr("Deactivate"));
    m_configurePluginButton = new QPushButton(tr("Configure"));
    m_viewDetailsButton = new QPushButton(tr("Details"));

    pluginButtonLayout->addWidget(m_loadPluginButton);
    pluginButtonLayout->addWidget(m_unloadPluginButton);
    pluginButtonLayout->addWidget(m_activatePluginButton);
    pluginButtonLayout->addWidget(m_deactivatePluginButton);
    pluginButtonLayout->addWidget(m_configurePluginButton);
    pluginButtonLayout->addWidget(m_viewDetailsButton);
    pluginButtonLayout->addStretch();

    // Plugin details
    QGroupBox* detailsGroup = new QGroupBox(tr("Plugin Details"));
    QVBoxLayout* detailsLayout = new QVBoxLayout(detailsGroup);

    m_pluginDetailsEdit = new QTextEdit();
    m_pluginDetailsEdit->setReadOnly(true);
    m_pluginDetailsEdit->setMaximumHeight(100);

    m_pluginStatus = new QLabel(tr("No plugin selected"));
    m_pluginStatus->setStyleSheet("QLabel { color: gray; font-style: italic; }");

    detailsLayout->addWidget(m_pluginDetailsEdit);
    detailsLayout->addWid


#include "Client.h"

#include <include/cef_browser.h>
#include <include/cef_command_line.h>
#include <include/cef_origin_whitelist.h>
#include <include/cef_request.h>
#include <include/cef_sandbox_win.h>
#include <include/wrapper/cef_helpers.h>

#include <string>
#include <iostream>

OffscreenClient::OffscreenClient(HWND host_window, std::shared_ptr<Presenter> presenter, int width, int height, float scale)
    : host_window_(host_window), presenter_(std::move(presenter)), width_(width), height_(height), scale_(scale) {
  std::cout << "[Client] OffscreenClient created (" << width << "x" << height << ", scale=" << scale << ")\n";
}

void OffscreenClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();
  browser_ = browser;
  std::cout << "[Client] Browser created successfully! ID: " << browser->GetIdentifier() << "\n";

  // Force an invalidation to trigger paint events
  browser->GetHost()->Invalidate(PET_VIEW);
  std::cout << "[Client] Forced browser invalidation to trigger paint\n";
}

void OffscreenClient::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();
  std::cout << "[Client] Browser closing... ID: " << browser->GetIdentifier() << "\n";
  browser_ = nullptr;
  // Signal that the browser is closed - this helps with shutdown
  if (host_window_) {
    PostMessage(host_window_, WM_DESTROY, 0, 0);
  }
  std::cout << "[Client] Browser closed\n";
}

void OffscreenClient::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
  rect = CefRect(0, 0, width_, height_);
  static bool logged = false;
  if (!logged) {
    std::cout << "[Client] GetViewRect called: " << width_ << "x" << height_ << "\n";
    logged = true;
  }
}

bool OffscreenClient::GetScreenInfo(CefRefPtr<CefBrowser> browser, CefScreenInfo& screen_info) {
  screen_info.device_scale_factor = scale_;
  screen_info.depth = 24;
  screen_info.depth_per_component = 8;
  screen_info.is_monochrome = false;
  screen_info.rect = CefRect(0, 0, width_, height_);
  screen_info.available_rect = screen_info.rect;
  static bool logged = false;
  if (!logged) {
    std::cout << "[Client] GetScreenInfo called: scale=" << scale_ << ", depth=24\n";
    logged = true;
  }
  return true;
}

void OffscreenClient::OnAcceleratedPaint(CefRefPtr<CefBrowser> browser,
                                         PaintElementType type,
                                         const RectList& dirty_rects,
                                         const CefAcceleratedPaintInfo& info) {
  CEF_REQUIRE_UI_THREAD();
  if (type != PET_VIEW) return;

  static int paint_count = 0;
  paint_count++;

  if (paint_count <= 10 || paint_count % 60 == 0) {
    std::cout << "[Client] OnAcceleratedPaint #" << paint_count << " - Handle: " << info.shared_texture_handle
              << ", Size: " << width_ << "x" << height_ << ", Format: " << info.format << "\n";
    std::cout << "[Client] Dirty rects count: " << dirty_rects.size() << "\n";
  }

  got_accel_.store(true, std::memory_order_relaxed);
  if (presenter_) {
    presenter_->PresentSharedHandle(info.shared_texture_handle, width_, height_);
  } else {
    std::cerr << "[Client] ERROR: No presenter available for OnAcceleratedPaint!\n";
  }
}

void OffscreenClient::OnPaint(CefRefPtr<CefBrowser> browser,
                              PaintElementType type,
                              const RectList& dirty_rects,
                              const void* buffer,
                              int width,
                              int height) {
  // Fallback path when GPU is disabled; not implemented for brevity.
  static int software_paint_count = 0;
  software_paint_count++;
  std::cout << "[Client] OnPaint (software) #" << software_paint_count << " - Size: " << width << "x" << height << "\n";
  std::cout << "[Client] WARNING: Software rendering fallback - GPU acceleration may not be working!\n";
}

void OffscreenClient::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) {
  CEF_REQUIRE_UI_THREAD();
  std::cout << "[Client] Title changed: " << title.ToString() << "\n";
  if (host_window_) SetWindowTextW(host_window_, std::wstring(title).c_str());
}

bool OffscreenClient::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                                     CefRefPtr<CefFrame> frame,
                                     CefRefPtr<CefRequest> request,
                                     bool user_gesture,
                                     bool is_redirect) {
  std::cout << "[Client] OnBeforeBrowse: " << request->GetURL().ToString() << "\n";
  return false;  // allow
}


#include <corecrt_wstdio.h>
#include <cstdio>
#include <stdint.h>
#include <stdio.h>
#include <vcruntime_string.h>
#include <vector>
#include "token.cpp"
#include "lexer.cpp"

enum AstType {
  TELOS_IMPORT_STMT,
  TELOS_CONST_DECL,
  TELOS_VAR_DECL,
};

struct Telos_Import {
  Token path;
};

struct Telos_Const {
  Token name;
  Token value;
};

struct Telos_Var {
  Token name;
  Token value;
};

struct Telos_Node {
  AstType type;
  union {
    Telos_Import import_stmt;
    Telos_Const const_stmt;
    Telos_Var var_stmt;
  };
};

struct Telos_Program {
  Telos_Node* statements;
  usize32 capacity;
  usize32 size;
};

void Telos_Add_Node(Telos_Program* program, Telos_Node node) {
  if (program->size >= program->capacity) {
    printf("realocing...\n");
    auto temp = (Telos_Node*) malloc(sizeof(Telos_Node) * program->capacity * 2);
    program->capacity *= 2;
    memcpy(temp, program->statements, program->capacity * sizeof(Telos_Node));
    free(program->statements);
    program->statements = temp;
  }
  printf("adding node...\n");
  program->statements[program->size] = node;
  program->size++;
}

Telos_Program root = Telos_Program{ nullptr };

Token Telos_parse_literal(std::vector<Token> program, usize32 i) {
  switch(program[i].type) {
    case STRING_LITERAL :
    case KW_FALSE:
    case KW_TRUE:
    case INT_LITERAL:
    case FLOAT_LITERAL:
      return program[i];
    default: {
      char buffer[100];
      Token_Name(program[i], buffer);
      fprintf(stderr,
              "Erro (%zu:%zu) Expected Literal but got %s\n",
              program[i].line, program[i].col, buffer);
      exit(2);
    }
  }
}
Token Telos_parse_type(std::vector<Token> program, usize32 i) {
  switch (program[i].type) {
  case I8:
  case I16:
  case I32:
  case I64:
  case F8:
  case F16:
  case F32:
  case F64:
  case U8:
  case U16:
  case U32:
  case U64:
      return program[i];
  default: {
      fprintf(stderr, "Erro (%zu:%zu) Expected type but got %d\n",
              program[i].line, program[i].col, program[i].type);
      exit(2);
  }
  }
}

void parser_outside_statements(std::vector<Token> program, usize32 &i) {
  while (i < program.size()) {
      switch (program[i].type) {
      case IDENTIFIER: {

        // NOTE(doug): parse constants
        if (i + 1 < program.size() && program[i + 1].type == TY_DESC) {
          auto lit = Telos_parse_literal(program, i + 2);
          Telos_Const stmt = {};
          stmt.name = program[i];
          stmt.value = program[i + 2];
          Telos_Node x = {};
          x.type = TELOS_CONST_DECL;
          x.const_stmt = stmt;
          Telos_Add_Node(&root, x);
          i += 2;
        }// NOTE(doug): parse vars
        else if (i + 1 < program.size() && program[i + 1].type == TY_ASS) {
          auto type = Telos_parse_type(program, i + 2);

          if (program[i + 3].type != OP_ASS)  {
            fprintf(stderr, "Erro (%zu:%zu) Expected '=' but got %d\n",
                    program[i].line, program[i].col, program[i].type);
            exit(2);
          }
          // parse expression
          Telos_Var stmt = {};
          stmt.name = program[i];
          stmt.value = program[i + 2];
          Telos_Node x = {};
          x.type = TELOS_VAR_DECL;
          x.var_stmt = stmt;
          Telos_Add_Node(&root, x);
          i += 4;
        }
      } break;
      case KW_IMPORT: {
        if (i + 1 < program.size() && program[i + 1].type == STRING_LITERAL) {
          Telos_Add_Node(&root, Telos_Node{TELOS_IMPORT_STMT, program[i + 1]});
          i +=1;
        } else {
          fprintf(stderr,
                  "Erro (%zu:%zu) `import` deve ser seguido de uma string\n",
                  program[i].line, program[i].col);
          exit(1);
        }
      } break;
      default: {
        char buffer[100];
        Token_Name(program[i], buffer);
        printf("saiu pq entrou aqui %s ??\n", buffer);
        return;
      }
      }
      i++;
  }
}

void parse_program(std::vector<Token> program) {
  usize32 i = 0;
  parser_outside_statements(program, i);
}

int main(int argc, char *argv[]) {
    char input[] = "import \"teste\"\n x :: 69\n PI :: 3.141569\n z: i32 =";
    auto program = Lexer_parse_program(input);
    char buffer[100];
    for(auto &token : program) {
        Token_Name(token, buffer);
        printf("Token of type %s \n", buffer);
    }
    root.statements = (Telos_Node*) malloc(sizeof(Telos_Node) * 100);
    root.size = 0;
    root.capacity = 100;
    parse_program(program);

    printf("Program size %zu: \n", root.size);
    for (usize32 i = 0; i < root.size; i++ ){
      printf("stmt type %d: \n", root.statements[i].type);
      switch(root.statements[i].type) {
        case TELOS_IMPORT_STMT: {
          Token_Name(root.statements[i].import_stmt.path, buffer);
          printf("Importing %s: \n", buffer);
        } break;
        case TELOS_CONST_DECL: {
          Token_Name(root.statements[i].const_stmt.name, buffer);
          printf("%s :: ", b


/*

Copyright (c) 2009, 2011, 2013-2014, 2016-2017, 2019-2020, Arvid Norberg
Copyright (c) 2015-2016, 2018, 2020, Alden Torres
Copyright (c) 2016, Andrei Kurushin
All rights reserved.

You may use, distribute and modify this code under the terms of the BSD license,
see LICENSE file.
*/

#include "libTAU/aux_/bandwidth_manager.hpp"

#if TORRENT_USE_ASSERTS
#include <climits>
#endif

namespace libTAU {
namespace aux {

	bandwidth_manager::bandwidth_manager(int channel)
		: m_queued_bytes(0)
		, m_channel(channel)
		, m_abort(false)
	{
	}

	void bandwidth_manager::close()
	{
		m_abort = true;

		std::vector<bw_request> queue;
		queue.swap(m_queue);
		m_queued_bytes = 0;

		while (!queue.empty())
		{
			bw_request& bwr = queue.back();
			bwr.peer->assign_bandwidth(m_channel, bwr.assigned);
			queue.pop_back();
		}
	}

#if TORRENT_USE_ASSERTS
	bool bandwidth_manager::is_queued(bandwidth_socket const* peer) const
	{
		for (auto const& r : m_queue)
		{
			if (r.peer.get() == peer) return true;
		}
		return false;
	}
#endif

	int bandwidth_manager::queue_size() const
	{
		return int(m_queue.size());
	}

	std::int64_t bandwidth_manager::queued_bytes() const
	{
		return m_queued_bytes;
	}

	// non prioritized means that, if there's a line for bandwidth,
	// others will cut in front of the non-prioritized peers.
	// this is used by web seeds
	int bandwidth_manager::request_bandwidth(std::shared_ptr<bandwidth_socket> peer
		, int const blk, int const priority, bandwidth_channel** chan, int const num_channels)
	{
		INVARIANT_CHECK;
		if (m_abort) return 0;

		TORRENT_ASSERT(blk > 0);
		TORRENT_ASSERT(priority > 0);

		// if this assert is hit, the peer is requesting more bandwidth before
		// being assigned bandwidth for an already outstanding request
		TORRENT_ASSERT(!is_queued(peer.get()));

		if (num_channels == 0)
		{
			// the connection is not rate limited by any of its
			// bandwidth channels, or it doesn't belong to any
			// channels. There's no point in adding it to
			// the queue, just satisfy the request immediately
			return blk;
		}

		int k = 0;
		bw_request bwr(std::move(peer), blk, priority);
		for (int i = 0; i < num_channels; ++i)
		{
			if (chan[i]->need_queueing(blk))
				bwr.channel[k++] = chan[i];
		}

		if (k == 0) return blk;

		m_queued_bytes += blk;
		m_queue.push_back(std::move(bwr));
		return 0;
	}

#if TORRENT_USE_INVARIANT_CHECKS
	void bandwidth_manager::check_invariant() const
	{
		std::int64_t queued = 0;
		for (auto const& r : m_queue)
		{
			queued += r.request_size - r.assigned;
		}
		TORRENT_ASSERT(queued == m_queued_bytes);
	}
#endif

	void bandwidth_manager::update_quotas(time_duration const& dt)
	{
		if (m_abort) return;
		if (m_queue.empty()) return;

		INVARIANT_CHECK;

		std::int64_t dt_milliseconds = total_milliseconds(dt);
		if (dt_milliseconds > 3000) dt_milliseconds = 3000;

		// for each bandwidth channel, call update_quota(dt)

		std::vector<bandwidth_channel*> channels;

		std::vector<bw_request> queue;

		for (auto i = m_queue.begin(); i != m_queue.end();)
		{
			if (i->peer->is_disconnecting())
			{
				m_queued_bytes -= i->request_size - i->assigned;

				// return all assigned quota to all the
				// bandwidth channels this peer belongs to
				for (int j = 0; j < bw_request::max_bandwidth_channels && i->channel[j]; ++j)
				{
					bandwidth_channel* bwc = i->channel[j];
					bwc->return_quota(i->assigned);
				}

				i->assigned = 0;
				queue.push_back(std::move(*i));
				i = m_queue.erase(i);
				continue;
			}
			for (int j = 0; j < bw_request::max_bandwidth_channels && i->channel[j]; ++j)
			{
				bandwidth_channel* bwc = i->channel[j];
				bwc->tmp = 0;
			}
			++i;
		}

		for (auto const& r : m_queue)
		{
			for (int j = 0; j < bw_request::max_bandwidth_channels && r.channel[j]; ++j)
			{
				bandwidth_channel* bwc = r.channel[j];
				if (bwc->tmp == 0) channels.push_back(bwc);
				TORRENT_ASSERT(INT_MAX - bwc->tmp > r.priority);
				bwc->tmp += r.priority;
			}
		}

		for (auto const& ch : channels)
		{
			ch->update_quota(int(dt_milliseconds));
		}

		for (auto i = m_queue.begin(); i != m_queue.end();)
		{
			int a = i->assign_bandwidth();
			if (i->assigned == i->request_size
				|| (i->ttl <= 0 && i->assigned > 0))
			{
				a += i->request_size - i->assigned;
				TORRENT_ASSERT(i->assigned <= i->request_size);
				queue.push_back(std::move(*i));
				i = m_queue.erase(i);
			}
			else
			{
				++i;
			}
			m_queued_bytes -= a;
		}

		while (!queue.empty())
		{
			bw_request& bwr = queue.back();
			bwr.peer->assign_bandwidth(m_channel, bwr.assigned);
			queue.pop_back();
		}
	}
}
}


/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   main.cpp                                           :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: smarquez <smarquez@student.42.fr>          +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2025/09/01 12:59:32 by smarquez          #+#    #+#             */
/*   Updated: 2025/09/01 13:28:32 by smarquez         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "Zombie.hpp"

int main()
{

    randomChump("ChumpZombie");

    Zombie *heapzombie = newZombie("heapzombie");
    heapzombie->announce();
    delete heapzombie;

    randomChump("StackZombie");
    return(0);
}


// Copyright 2017, Philipp Neufeld

// Only available on windows
#include "Platform.h"
#ifdef EAGLE_PLATFORM_WINDOWS

// Includes
#include "DX11DeferredRenderer.h"
#include "Path.h"

namespace Eagle
{

	CDX11DeferredRenderer::CDX11DeferredRenderer()
	{
	}

	bool CDX11DeferredRenderer::Create(CDX11RenderingSystem * pRenderingSystem, const char * shaderDirectory)
	{
		_SetInitializationState(false);

		// validate arguments
		if (!shaderDirectory || !pRenderingSystem)
			return false;

		if (!m_postProcessingRenderer.Create(pRenderingSystem, shaderDirectory))
			return false;

		// validate device
		ID3D11Device* pDevice = pRenderingSystem->GetDevice();
		if (!pDevice)
			return false;

		// load pixel shader
		std::string psPath = AppendPath(shaderDirectory, "DX11DeferredPixelShader.cso");

		if (!m_pixelShader.CreateFromCSOFile(pDevice, psPath.c_str()))
			return false;

		// load location of all uniforms
		if (!_GetAllUniformLocations())
			return false;

		_SetInitializationState(true);
		return true;
	}

	void CDX11DeferredRenderer::Destroy()
	{
		_SetInitializationState(false);

		m_texturePosition = nullptr;
		m_textureNormal = nullptr;
		m_textureAmbient = nullptr;
		m_textureDiffuse = nullptr;
		m_textureSpecular = nullptr;

		m_sampler = nullptr;

		m_lightAmbient = nullptr;
		m_lightDiffuse = nullptr;
		m_lightSpecular = nullptr;
		m_lightDir = nullptr;

		m_eyePos = nullptr;

		m_pixelShader.Destroy();
		m_postProcessingRenderer.Destroy();
	}

	bool CDX11DeferredRenderer::Render(CDX11RenderingSystem * pRenderingSystem, CDX11DeferredRenderingGBuffer * pGBuffer, const IDX11RenderColorTarget * pColorTarget)
	{
		// validate arguments
		if (!pRenderingSystem || !pGBuffer || !pColorTarget)
			return false;

		// renderer has to be ready
		if (!_IsReadyToRender(pRenderingSystem))
			return false;

		// set texture and sampler
		_SetSampler(pRenderingSystem->GetSamplerLinearClamp());

		_SetPositionTexture(pGBuffer->GetPositionBuffer()->GetShaderResourceView());
		_SetNormalTexture(pGBuffer->GetNormalBuffer()->GetShaderResourceView());
		_SetAmbientTexture(pGBuffer->GetAmbientBuffer()->GetShaderResourceView());
		_SetDiffuseTexture(pGBuffer->GetDiffuseBuffer()->GetShaderResourceView());
		_SetSpecularTexture(pGBuffer->GetSpecularBuffer()->GetShaderResourceView());

		// set camera position
		_SetCameraPosition(pRenderingSystem->GetCameraPosition());

		// set light stats
		_SetAmbient(Color(0.25f, 0.25f, 0.25f, 1.0f));
		_SetDiffuse(Color(0.75f, 0.75f, 0.75f, 1.0f));
		_SetSpecular(Color(0.5f, 0.5f, 0.5f, 1.0f));

		_SetLightDirection(Vector3f(1.0f, -0.5f, -1.0f));

		if (!m_postProcessingRenderer.Render(pRenderingSystem, &m_pixelShader, &pColorTarget, 1,
			pColorTarget->GetViewport(), pRenderingSystem->GetBSDefault()))
			return false;

		return true;
	}

	bool CDX11DeferredRenderer::_GetAllUniformLocations()
	{
		m_texturePosition = m_pixelShader.GetUniformLocationSRV("g_texturePosition");
		m_textureNormal = m_pixelShader.GetUniformLocationSRV("g_textureNormal");
		m_textureAmbient = m_pixelShader.GetUniformLocationSRV("g_textureAmbient");
		m_textureDiffuse = m_pixelShader.GetUniformLocationSRV("g_textureDiffuse");
		m_textureSpecular = m_pixelShader.GetUniformLocationSRV("g_textureSpecular");

		m_sampler = m_pixelShader.GetUniformLocationSampler("g_sampler");

		m_lightAmbient = m_pixelShader.GetUniformLocationCBVariable("g_lightAmbient");
		m_lightDiffuse = m_pixelShader.GetUniformLocationCBVariable("g_lightDiffuse");
		m_lightSpecular = m_pixelShader.GetUniformLocationCBVariable("g_lightSpecular");
		m_lightDir = m_pixelShader.GetUniformLocationCBVariable("g_lightDir");

		m_eyePos = m_pixelShader.GetUniformLocationCBVariable("g_eyePos");

		return true;
	}

	void CDX11DeferredRenderer::_SetPositionTexture(ID3D11ShaderResourceView * pTexture)
	{
		if (m_texturePosition)
			m_texturePosition.SetValue(pTexture);
	}

	void CDX11DeferredRenderer::_SetNormalTexture(ID3D11ShaderResourceView * pTexture)
	{
		if (m_textureNormal)
			m_textureNormal.SetValue(pTexture);
	}

	void CDX11DeferredRenderer::_SetAmbientTexture(ID3D11ShaderResourceView * pTexture)
	{
		if (m_textureAmbient)
			m_textureAmbient.SetValue(pTexture);
	}

	void CDX11DeferredRenderer::_SetDiffuseTexture(ID3D11ShaderResourceView * pTexture)
	{
		if (m_textureDiffuse)
			m_textureDiffuse.SetValue(pTexture);
	}

	void CDX11DeferredRenderer::_SetSpecularTexture(ID3D11ShaderResourceView * pTexture)
	{
		if (m_textureSpecular)
			m_textureSpecular.SetValue(pTexture);
	}

	void CDX11DeferredRenderer::_SetSampler(ID3D11SamplerState * pSampler)
	{
		if (m_sampler)
			m_sampler.SetValue(pSampler);
	}

	void CDX11DeferredRenderer::_SetAmbient(FColor col)
	{
		if (m_lightAmbient)
			m_lightAmbient.SetFloat4(col);
	}

	void CDX11DeferredRenderer::_SetDiffuse(FColor col)
	{
		if (m_lightDiffuse)
			m_lightDiffuse.SetFloat4(col);
	}

	void CDX11DeferredRenderer::_SetSpecular(FColor col)
	{
		if (m_lightSpecular)
			m_lightSpecular.SetFlo


#include <iostream>
#include <fstream>
using namespace std;

class temp
{
    string userName, Email, Password;
    string searchName, searchPass, searchEmail;
    fstream file;

public:
    void login();
    void signup();
    void forgot();

} obj;
int main()
{
    char choice;
    cout << "1- login " << "\n";
    cout << "2- Sign-Up " << "\n";
    cout << "3- Forgot Password " << "\n";
    cout << "4- Exit " << "\n";
    cin >> choice;
    switch (choice)
    {
    case '1':
        obj.login();
        break;

    case '2':
        obj.signup();
        break;

    case '3':
        obj.forgot();
        break;

    case '4':
        return 0;
        break;

    default:
        cout << "wrong input";
    }
    return 0;
}
void temp ::signup()
{
    cin.ignore();
    cout << "\n enter your username :: ";
    getline(cin, userName);
    cout << "\n ener your email address :: ";
    getline(cin, Email);
    cout << "\n enter the password :: ";
    getline(cin, Password);

    file.open("loginData.txt", ios ::out | ios ::app);
    file << userName << "*" << Email << "*" << Password << endl;
    file.close();
}

void temp ::login()
{
    cin.ignore();
    string searchName, searchPass;
    cout << "------------login------------" << endl;
    cout << "\n enter your username :: ";
    getline(cin, searchName);
    cout << "\n enter your password :: ";
    getline(cin, searchPass);

    file.open("loginData.txt", ios ::in);
    getline(file, userName, '*');
    getline(file, Email, '*');
    getline(file, Password, '\n');
    while (!file.eof())
    {
        if (userName == searchName)
        {
            if (Password == searchPass)
            {
                cout << "login sucessful!" << endl;
            }
            else
                cout << "incorrect password" << endl;
        }
        getline(file, userName, '*');
        getline(file, Email, '*');
        getline(file, Password, '\n');
    }
    file.close();
}

void temp::forgot()
{
    cin.ignore();
    cout << "Enter your username: ";
    getline(cin, userName);
    cout << "Enter your Email: ";
    getline(cin, Email);

    bool found = false;
    string line, uname, mail, pass;
    ifstream infile("loginData.txt");
    ofstream outfile("temp.txt");
    while (getline(infile, line))
    {
        size_t pos1 = line.find('*');
        size_t pos2 = line.find('*', pos1 + 1);
        if (pos1 != string::npos && pos2 != string::npos)
        {
            uname = line.substr(0, pos1);
            mail = line.substr(pos1 + 1, pos2 - pos1 - 1);
            pass = line.substr(pos2 + 1);

            if (uname == userName && mail == Email)
            {
                found = true;
                cout << "Account found!\n";
                cout << "Your password: " << pass << endl;
                cout << "Do you want to change your password? (y/n): ";
                char ch;
                cin >> ch;
                cin.ignore();
                if (ch == 'y' || ch == 'Y')
                {
                    cout << "Enter new password: ";
                    string newPass;
                    getline(cin, newPass);
                    outfile << uname << "*" << mail << "*" << newPass << endl;
                    cout << "Password changed successfully!\n";
                }
                else
                {
                    outfile << line << endl;
                }
            }
            else
            {
                outfile << line << endl;
            }
        }
    }
    infile.close();
    outfile.close();

    // Replace old file with updated file
    remove("loginData.txt");
    rename("temp.txt", "loginData.txt");

    if (!found)
        cout << "Account not found!\n";
}