#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "wslib.h"
#include <io.h>
#include <commctrl.h> 
#include <shlobj.h>


#pragma comment(lib, "comctl32.lib")

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);


#define ID_BUTTON_TOSC 1001
#define ID_BUTTON_FROMSC 1002
#define ID_BUTTON_CLOSE 1003
#define ID_BUTTON_STOP 1004
#define ID_TXT 1005

HWND hwndProgress;
HWND txtWindow;

int progressPos = 0;
int started = 0;
int stop = 0;
 int progresZ = -1;
HANDLE hThread = NULL;
char current_path[MAX_PATH];
char current_path2[MAX_PATH];
char tab2[255];
char inputFilePath[MAX_PATH] = ""; // Globalna zmienna na ścieżkę wybranego pliku
char outputFilePath[MAX_PATH] = ""; // Globalna zmienna na ścieżkę wybranego pliku

DWORD WINAPI BackgroundThreadFunction(LPVOID lpParam);

DWORD WINAPI BackgroundThreadFunction_2(LPVOID lpParam);
// Funkcja wątku tła
DWORD WINAPI BackgroundThreadFunction(LPVOID lpParam) {
    HWND hwnd = (HWND)lpParam;
    started = 1;
    
    char *ptr = strrchr(inputFilePath, '\\');
    if (ptr == NULL) {
        MessageBox(NULL, "Nie znaleziono '\\' w ścieżce pliku", "Błąd", MB_ICONERROR | MB_OK);
        return 1;
    }

    // Przesunięcie wskaźnika, aby zacząć od następnego znaku po '\'
    ptr++;

    // Skopiowanie części ścieżki po ostatnim znaku '\' do buff
    char buff[400];
    strcpy(buff, ptr);
    
    char buffer2[400];
    //MessageBox(NULL, buffer2, "Błąd", MB_ICONERROR | MB_OK);
    FILE *out = fopen(outputFilePath, "wb");

    // Konwersja liczby int na łańcuch znaków
    sprintf(buffer2, "%s", ptr, strlen(buff));
    
    struct safeObject myObject2;
    createSafeObjectFromString(&myObject2, buffer2);
    
    char *tmp = myObject2.sObjectStart;
    //MessageBox(NULL, tmp, "Błąd", MB_ICONERROR | MB_OK);
    
    for (int i = 0; i < myObject2.sSize; i++) {
        fprintf(out, "%c", *tmp);
        tmp++;
    }
    
    fprintf(out, "%c", '|');
    progresZ = -1;

    
    struct safeObject myObject;
    createSafeObjectFromFile(&myObject, inputFilePath);
  //  MessageBox(NULL, "tmp", "Błąd", MB_ICONERROR | MB_OK);
    tmp = myObject.sObjectStart;
    float proc;
    char tmp_text[1000];
    strcpy(tmp_text, "Saving chars   \n   from      ");
    strcat(tmp_text, inputFilePath);
    strcat(tmp_text, " \nto ");
    strcat(tmp_text, outputFilePath);
    
    SetWindowText(txtWindow, tmp_text);
    
    for (int i = 0; i < myObject.sSize; i++) {
        proc = ((float)i / myObject.sSize) * 100; 
        if ((int)proc != progresZ) {
            progresZ = (int)proc;
            //  printf("Progress: %d%%\n", z);
            SendMessage(hwndProgress, PBM_SETPOS, progresZ, 0);
            //PostMessage(hwnd, WM_USER + 1, 0, 0);
        }
        fprintf(out, "%c", *tmp);
        tmp++;
        if (stop == 1) {
            stop = 0;
            started = 0;
            break;
        }
    }
    
    SendMessage(hwndProgress, PBM_SETPOS, 0, 0);                                    
    fclose(out);
    SetWindowText(txtWindow, "Done!");
    
    free(myObject.sObjectStart);
    free(myObject2.sObjectStart);
    
    return 0;
}



DWORD WINAPI BackgroundThreadFunction_2(LPVOID lpParam) {
    HWND hwnd = (HWND)lpParam;
      started=1;
      OPENFILENAME ofn;
                    ZeroMemory(&ofn, sizeof(ofn));
                    ofn.lStructSize = sizeof(ofn);
                    ofn.hwndOwner = hwnd;
                    ofn.lpstrFile = inputFilePath;
                    ofn.lpstrFile[0] = '\0';
                    ofn.nMaxFile = sizeof(inputFilePath);
                    ofn.lpstrFilter = "Wszystkie pliki\0*.*\0";
                    ofn.nFilterIndex = 1;
                    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;

                    if (GetOpenFileName(&ofn)) {
                     
                      FILE *file = fopen(inputFilePath, "rb");


    
char last_byte;
char tmp;
char tab[20];
char tmpsch[3];
tmpsch[2]='\0';
int rozmiar=0;
char nazwa[1000];
char *ptr;
 for(int i=0;i<1000;i++){nazwa[i]='\0';}
ptr=tmpsch;
int j=0;
while(tmp!='|'){
                                
                                 tmp = fgetc(file);
                                 tmpsch[0]=tmp;
                                 if(tmp=='|'){nazwa[j]='\0';break;}
                                 tmp = fgetc(file);
                                 tmpsch[1]=tmp;                                 
                                 char d  =  getSafeCharCode(ptr);
                                // printf("%c",d);
                                 nazwa[j]=d;j++;}
fclose(file);
nazwa[j]='\0';

file = fopen(inputFilePath, "r");
long long tk=0;
long long rozm = getFileSize(inputFilePath);
char *tmp_tablica = new char[rozm+1];
ptr = tmp_tablica;
for(long long i=0,tk=0;i<rozm;i++,tk++){*ptr='\0';ptr++;}

tmp='s';
while(tmp!='|'){
                                
                tmp = fgetc(file);}
 float proc;
ptr = tmp_tablica;
int i2=0;
progresZ=0;
 SetWindowText(txtWindow,"Searching for chars to save!");
while(!feof(file)){
                   i2++;
                   proc = ((float)i2 /rozm) * 100; 
                                                                         if ((int)proc != progresZ) {
                                                                         progresZ = (int)proc;
                                                                       
                                                                        SendMessage(hwndProgress, PBM_SETPOS, progresZ, 0);
                                                 if(stop==1){fclose(file);delete [] tmp_tablica;stop=0;started=0; SendMessage(hwndProgress, PBM_SETPOS, 0, 0);    return 0;}                      
                                                                        }
                   tmp = fgetc(file);*ptr=tmp;ptr++;

}
 SendMessage(hwndProgress, PBM_SETPOS, 0, 0);
*ptr='\0';
fclose(file);

char nowiutka_nazwa[1000];
//MessageBox(NULL,"Zapis do pliku z RAM", "Błąd", MB_ICONERROR | MB_OK);


////////////////////////////////////////////////////////////////////////
    BROWSEINFO bi = {0};
    TCHAR path[MAX_PATH];
    bi.lpszTitle = "Wybierz katalog";
    bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
bi.hwndOwner = hwnd; 
    LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
    if (pidl != 0) {
        // Uzyskaj wybrany katalog
        SHGetPathFromIDList(pidl, path);
        printf("Wybrany katalog: %s\n", path);

strcpy(nowiutka_nazwa,path);strncat(nowiutka_nazwa,"\\",2);strncat(nowiutka_nazwa,nazwa,strlen(nazwa));

        // Zwolnij pamięć
        IMalloc *imalloc = 0;
        if (SUCCEEDED(SHGetMalloc(&imalloc))) {
            imalloc->Free(pidl);
            imalloc->Release();
        }
    } else {
       MessageBox(NULL,"Not gonna play your games anymore!", "Błąd", MB_ICONERROR | MB_OK);
      delete [] tmp_tablica;stop=0;started=0;return 0;
    }


////////////////////////////////////////////////////////////////////////



file = fopen(nowiutka_nazwa, "wb");
ptr = tmp_tablica;

SetWindowText(txtWindow,"Saving chars to file");
for(long long i=0,tk=0;i<rozm;i+=2,tk++){
                                           proc = ((float)i /rozm) * 100; 
                                                                         if ((int)proc != progresZ) {
                                                                         progresZ = (int)proc;
                                                                       
                                                                        SendMessage(hwndProgress, PBM_SETPOS, progresZ, 0);
                                      if(stop==1){fclose(file);delete [] tmp_tablica;stop=0;started=0; SendMessage(hwndProgress, PBM_SETPOS, 0, 0);    return 0;}       
                                                                        }

                                       char d  =  (char)getSafeCharCode(ptr);
                                       fprintf(file,"%c",d); ptr+=2;if(*ptr=='\0'){break;fclose(file);}}

 SendMessage(hwndProgress, PBM_SETPOS, 0, 0);                                  
fclose(file);
delete [] tmp_tablica;
file = fopen(nowiutka_nazwa, "r+");
    if (file == NULL) {
        perror("Nie można otworzyć pliku");
        return 1;
    }

    // Ustaw wskaźnik pliku na koniec pliku
    if (fseek(file, 0, SEEK_END) != 0) {
        perror("Nie można ustawić wskaźnika na koniec pliku");
        fclose(file);
        return 1;
    }

    // Pobierz rozmiar pliku
    long fileSize = ftell(file);
    if (fileSize == -1) {
        perror("Nie można uzyskać rozmiaru pliku");
        fclose(file);
        return 1;
    }

    // Skróć plik o jeden bajt
    if (_chsize(_fileno(file), fileSize - 1) != 0) {
        perror("Nie można skrócić pliku");
        fclose(file);
        return 1;
    }

    
    fclose(file);
 SetWindowText(txtWindow,"It was so close man!\nBut we did it! You and I!\nWe are ment to do this together!    xD");
//MessageBox(NULL,"Done!", "Błąd", MB_ICONERROR | MB_OK);

}

    return 0;
}


// Procedura okna głównego
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE: {
            
            CreateWindow("BUTTON", "----> safeChars", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 20, 1, 200, 30, hwnd, (HMENU)ID_BUTTON_TOSC, NULL, NULL);

           
            CreateWindow("BUTTON", "Close / Zamknij", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 240,1, 200, 30, hwnd, (HMENU)ID_BUTTON_CLOSE, NULL, NULL);


           
            CreateWindow("BUTTON", " <---- safeChars", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 460, 1, 200, 30, hwnd, (HMENU)ID_BUTTON_FROMSC, NULL, NULL);
            
            CreateWindow("BUTTON", "Stop", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 570, 135, 100, 30, hwnd, (HMENU)ID_BUTTON_STOP, NULL, NULL);

 txtWindow=CreateWindow(  "STATIC","Make you move!", WS_VISIBLE | WS_CHILD,  15, 50, 640, 80,   hwnd, (HMENU)ID_TXT ,  ((LPCREATESTRUCT)lParam)->hInstance,NULL);
            hwndProgress = CreateWindowEx( 0, PROGRESS_CLASS, (LPTSTR)NULL,WS_CHILD | WS_VISIBLE,30, 135, 540, 15, hwnd, (HMENU)0, GetModuleHandle(NULL), NULL);
            break;
        }


        case WM_USER + 1:{
        // Obsługa komunikatu z wątku tła (np. aktualizacja interfejsu użytkownika)
        SendMessage(hwndProgress, PBM_SETPOS, progresZ, 0);
        break;
                }

        case WM_COMMAND: {
            switch (LOWORD(wParam)) {



                 case ID_BUTTON_STOP: {
                                      if(started==1){started = 0;}
                                      stop=1;break;}
                case ID_BUTTON_TOSC: {

                    OPENFILENAME ofn;
                    ZeroMemory(&ofn, sizeof(ofn));
                    ofn.lStructSize = sizeof(ofn);
                    ofn.hwndOwner = hwnd;
                    ofn.lpstrFile = inputFilePath;
                    ofn.lpstrFile[0] = '\0';
                    ofn.nMaxFile = sizeof(inputFilePath);
                    ofn.lpstrFilter = "Wszystkie pliki\0*.*\0";
                    ofn.nFilterIndex = 1;
                    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;

                    if (!GetOpenFileName(&ofn)) {
                       MessageBox(NULL, "No file selected", "!", MB_ICONINFORMATION | MB_OK);break;
                    }

                  

    
    // Wyzerowanie pamięci struktury OPENFILENAME
    ZeroMemory(&ofn, sizeof(ofn));

    // Ustawienie pól struktury OPENFILENAME
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = NULL; // lub hwnd, jeśli masz uchwyt okna
    ofn.lpstrFile = outputFilePath;
    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = sizeof(outputFilePath);

    // Filtr plików, ustawienie domyślnego rozszerzenia na .html
    ofn.lpstrFilter = "Pliki HTML\0*.html\0Wszystkie pliki\0*.*\0";
    ofn.nFilterIndex = 1;
    ofn.lpstrDefExt = "html";
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;

    // Otwieranie okna dialogowego zapisu pliku
    if (GetSaveFileName(&ofn)) {
        // Kod obsługujący zapis wybranego pliku
        FILE *output_file = fopen(outputFilePath, "w");
        if (output_file) {
            fprintf(output_file, "Przykładowa zawartość pliku HTML.\n");
            fclose(output_file);
           // MessageBox(NULL, "Plik został zapisany./file was written", "Informacja", MB_ICONINFORMATION | MB_OK);
        } else {
            MessageBox(NULL, "Błąd przy zapisie pliku.", "Błąd", MB_ICONERROR | MB_OK);
        }
    } else {
        DWORD dwError = CommDlgExtendedError();
        if (dwError != 0) {
            char errorMsg[256];
            sprintf(errorMsg, "Błąd przy otwieraniu okna dialogowego. Kod błędu: %lu", dwError);
            MessageBox(NULL, errorMsg, "Błąd", MB_ICONERROR | MB_OK);
        }
    }

                    if (strlen(inputFilePath) > 0 && strlen(outputFilePath) > 0 ) {
                                      
                           
        hThread = CreateThread(
            NULL, 0, BackgroundThreadFunction, hwnd, 0, NULL);
        if (hThread == NULL) {
            MessageBox(hwnd, "Nie udało się utworzyć wątku", "Błąd", MB_OK | MB_ICONERROR);
        }


                            
                    } else {
                        MessageBox(NULL, "Wybierz najpierw pliki / choose files", "Błąd", MB_ICONERROR | MB_OK);
                    }
                    break;
                }


                case ID_BUTTON_FROMSC: {
         hThread = CreateThread(
            NULL, 0, BackgroundThreadFunction_2, hwnd, 0, NULL);
        if (hThread == NULL) {
            MessageBox(hwnd, "Nie udało się utworzyć wątku", "Błąd", MB_OK | MB_ICONERROR);
        }


                  
  
                       break;

                                      }

                case ID_BUTTON_CLOSE: {
                    DestroyWindow(hwnd);
                    break;
                }
                
            
          }
           break;
        }
        case WM_DESTROY: {
            PostQuitMessage(0);
            break;
        }
        default: {
            return DefWindowProc(hwnd, msg, wParam, lParam);
        }
    }
    return 0;
}

// Główna funkcja programu
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASS wc = {0};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = "FileWriterWinapiClass";

GetCurrentDirectory(MAX_PATH, current_path);
GetCurrentDirectory(MAX_PATH, current_path2);

    if (!RegisterClass(&wc)) {
        MessageBox(NULL, "Nie można zarejestrować klasy okna.", "Błąd", MB_ICONERROR | MB_OK);
        return 0;
    }

    HWND hwnd = CreateWindow("FileWriterWinapiClass", "Wojtek Sobiesiak safeChars for Windows", WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT, CW_USEDEFAULT, 700,210, NULL, NULL, hInstance, NULL);

    if (hwnd == NULL) {
        MessageBox(NULL, "Nie można utworzyć okna.", "Błąd", MB_ICONERROR | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

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

    return msg.wParam;
}
