#include <windows.h>
#include <wincodec.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Простая структура для хранения данных QR-кода
typedef struct {
    int version;
    int size;
    unsigned char* data;
} QRCode;

// Функция для создания QR-кода (упрощенная реализация)
QRCode* create_qr_code(const char* text) {
    if (!text || strlen(text) == 0) {
        return NULL;
    }
    
    // В реальной реализации здесь должна быть библиотека генерации QR-кода
    // Для примера создаем простой "заглушечный" QR-код
    QRCode* qr = (QRCode*)malloc(sizeof(QRCode));
    if (!qr) return NULL;
    
    qr->version = 1;
    qr->size = 21; // Размер QR-кода версии 1
    
    // Выделяем память для данных (1 бит на модуль)
    int data_size = (qr->size * qr->size + 7) / 8;
    qr->data = (unsigned char*)malloc(data_size);
    if (!qr->data) {
        free(qr);
        return NULL;
    }
    
    memset(qr->data, 0, data_size);
    
    // Простой паттерн для демонстрации
    for (int i = 0; i < qr->size; i++) {
        for (int j = 0; j < qr->size; j++) {
            if (i == 0 || i == qr->size - 1 || j == 0 || j == qr->size - 1 || 
                (i + j) % 3 == 0) {
                int bit_pos = i * qr->size + j;
                qr->data[bit_pos / 8] |= (1 << (bit_pos % 8));
            }
        }
    }
    
    return qr;
}

// Функция для отрисовки QR-кода в окне
void draw_qr_code(HDC hdc, QRCode* qr, int x, int y, int scale) {
    if (!qr || !qr->data) return;
    
    HBRUSH black_brush = CreateSolidBrush(RGB(0, 0, 0));
    HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255));
    
    // Рисуем QR-код
    for (int i = 0; i < qr->size; i++) {
        for (int j = 0; j < qr->size; j++) {
            int bit_pos = i * qr->size + j;
            int is_black = qr->data[bit_pos / 8] & (1 << (bit_pos % 8));
            
            HBRUSH brush = is_black ? black_brush : white_brush;
            RECT rect = {
                x + j * scale,
                y + i * scale,
                x + (j + 1) * scale,
                y + (i + 1) * scale
            };
            
            FillRect(hdc, &rect, brush);
        }
    }
    
    DeleteObject(black_brush);
    DeleteObject(white_brush);
}

// Функция для сохранения QR-кода в BMP файл
BOOL save_qr_to_bmp(QRCode* qr, const char* filename, int scale) {
    if (!qr || !filename) return FALSE;
    
    int width = qr->size * scale;
    int height = qr->size * scale;
    
    // Создаем временный HDC для рисования
    HDC hdc = GetDC(NULL);
    HDC mem_dc = CreateCompatibleDC(hdc);
    
    BITMAPINFO bmi = {0};
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = -height; // Отрицательная высота для top-down DIB
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;
    
    void* bits;
    HBITMAP hbitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
    
    if (!hbitmap) {
        DeleteDC(mem_dc);
        ReleaseDC(NULL, hdc);
        return FALSE;
    }
    
    SelectObject(mem_dc, hbitmap);
    
    // Рисуем белый фон
    RECT rect = {0, 0, width, height};
    HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255));
    FillRect(mem_dc, &rect, white_brush);
    
    // Рисуем QR-код
    draw_qr_code(mem_dc, qr, 0, 0, scale);
    
    // Сохраняем в файл
    BITMAPFILEHEADER bmfh = {0};
    bmfh.bfType = 0x4D42; // "BM"
    bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + width * height * 3;
    bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    
    FILE* file = fopen(filename, "wb");
    if (!file) {
        DeleteObject(hbitmap);
        DeleteDC(mem_dc);
        ReleaseDC(NULL, hdc);
        DeleteObject(white_brush);
        return FALSE;
    }
    
    fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, file);
    fwrite(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
    fwrite(bits, 1, width * height * 3, file);
    fclose(file);
    
    // Очистка ресурсов
    DeleteObject(hbitmap);
    DeleteDC(mem_dc);
    ReleaseDC(NULL, hdc);
    DeleteObject(white_brush);
    
    return TRUE;
}

// Оконная процедура
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    static QRCode* qr_code = NULL;
    static char input_text[256] = "Hello, World!";
    
    switch (msg) {
        case WM_CREATE: {
            // Создаем элементы управления
            CreateWindow("EDIT", input_text, WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
                        10, 10, 200, 25, hwnd, (HMENU)1, NULL, NULL);
            
            CreateWindow("BUTTON", "Generate QR", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
                        220, 10, 100, 25, hwnd, (HMENU)2, NULL, NULL);
            
            CreateWindow("BUTTON", "Save as BMP", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
                        330, 10, 100, 25, hwnd, (HMENU)3, NULL, NULL);
            
            // Создаем начальный QR-код
            if (qr_code) {
                free(qr_code->data);
                free(qr_code);
            }
            qr_code = create_qr_code(input_text);
            break;
        }
        
        case WM_COMMAND: {
            if (LOWORD(wParam) == 2) { // Кнопка Generate
                GetDlgItemText(hwnd, 1, input_text, sizeof(input_text));
                
                if (qr_code) {
                    free(qr_code->data);
                    free(qr_code);
                }
                qr_code = create_qr_code(input_text);
                InvalidateRect(hwnd, NULL, TRUE);
            }
            else if (LOWORD(wParam) == 3) { // Кнопка Save
                if (qr_code) {
                    save_qr_to_bmp(qr_code, "qrcode.bmp", 10);
                    MessageBox(hwnd, "QR-код сохранен как 'qrcode.bmp'", "Сохранение", MB_OK);
                }
            }
            break;
        }
        
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            
            // Рисуем QR-код
            if (qr_code) {
                draw_qr_code(hdc, qr_code, 50, 50, 10);
            }
            
            EndPaint(hwnd, &ps);
            break;
        }
        
        case WM_DESTROY: {
            if (qr_code) {
                free(qr_code->data);
                free(qr_code);
            }
            PostQuitMessage(0);
            break;
        }
        
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

// Точка входа
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    const char CLASS_NAME[] = "QRCodeGenerator";
    
    WNDCLASS wc = {0};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    
    RegisterClass(&wc);
    
    HWND hwnd = CreateWindow(
        CLASS_NAME,
        "QR Code Generator - C++/WinAPI",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 400,
        NULL, NULL, hInstance, NULL
    );
    
    if (!hwnd) {
        return 0;
    }
    
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    return msg.wParam;
}