/*******************************************************************************/

#include "PKR2EditorFrm.h"

/*******************************************************************************/
////Header Include Start
#include "Images/Self_PKR2EditorFrm_XPM.xpm"
////Header Include End

/*******************************************************************************/

////Event Table Start
BEGIN_EVENT_TABLE(PKR2EditorFrm,wxFrame)
	////Manual Code Start
	////Manual Code End
	
	EVT_CLOSE(PKR2EditorFrm::OnClose)
	EVT_BUTTON(ID_BTNNEWPKR,PKR2EditorFrm::BTNNewPkrClick)
	EVT_BUTTON(ID_BTNSAVEPKR,PKR2EditorFrm::BTNSavePkrClick)
	EVT_BUTTON(ID_BTNOPENPKR,PKR2EditorFrm::BTNOpenPkrClick)
	EVT_BUTTON(ID_BTNREPLACEFILE,PKR2EditorFrm::BTNReplaceFileClick)
	EVT_BUTTON(ID_BTNDELETEFILE,PKR2EditorFrm::BTNDeleteFileClick)
	EVT_BUTTON(ID_BTNEXTRACTFILE,PKR2EditorFrm::BTNExtractFileClick)
	EVT_BUTTON(ID_BTNADDFILE,PKR2EditorFrm::BTNAddFileClick)
	EVT_BUTTON(ID_BTNEXTDIR,PKR2EditorFrm::BTNExtDirClick)
	EVT_BUTTON(ID_BTNDELDIR,PKR2EditorFrm::BTNDelDirClick)
	EVT_BUTTON(ID_EDTADDDIR,PKR2EditorFrm::BTNAddDirClick)
	EVT_LISTBOX(ID_LSTFILES,PKR2EditorFrm::LSTFilesSelected)
	EVT_LISTBOX_DCLICK(ID_LSTFILES,PKR2EditorFrm::LSTFilesDoubleClicked)
	EVT_LISTBOX(ID_LSTDIRS,PKR2EditorFrm::LSTDirsSelected)
END_EVENT_TABLE()
////Event Table End

/*******************************************************************************/

PKR2EditorFrm::PKR2EditorFrm(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
: wxFrame(parent, id, title, position, size, style)
{
	CreateGUIControls();
	dirs_n = 0;
	files_n = 0;
	dirs = NULL;
	exdir = NULL;
	exfile = NULL;
	EDTText -> Show(false);
	HTMLBmp -> SetBorders(0);
	HTMLBmp -> Show(false);
}

/*******************************************************************************/

PKR2EditorFrm::~PKR2EditorFrm()
{
    ClearMem();
}

/*******************************************************************************/

void PKR2EditorFrm::CreateGUIControls()
{
	////GUI Items Creation Start

	BTNNewPkr = new wxButton(this, ID_BTNNEWPKR, wxT("New PKR File"), wxPoint(270, 0), wxSize(142, 21), 0, wxDefaultValidator, wxT("BTNNewPkr"));

	DLGNameInvalid =  new wxMessageDialog(this, wxT("Name invalid!, String min size: 1 character, String max size : 31 characters."), wxT("Warning"));

	DLGAddFile =  new wxFileDialog(this, wxT("Choose a file to add"), wxT(""), wxT(""), wxT("*.*"), wxOPEN | wxFILE_MUST_EXIST);

	DLGExtFolder =  new wxDirDialog(this, wxT("Extract folder"), wxT(""), wxDD_NEW_DIR_BUTTON);

	DLGSavePkr =  new wxFileDialog(this, wxT("Save PKR2 File"), wxT(""), wxT(""), wxT("*.pkr"), wxSAVE);

	DLGExtFile =  new wxFileDialog(this, wxT("Extract file"), wxT(""), wxT(""), wxT("*.*"), wxSAVE);

	DLGFileName =  new wxTextEntryDialog( this,wxT(""), wxT("Enter internal PKR2 file name:"), wxT("") ,wxOK | wxCANCEL | wxCENTRE);

	DLGFolderName =  new wxTextEntryDialog( this,wxT(""), wxT("Enter folder name"), wxT("") ,wxOK | wxCANCEL | wxCENTRE);

	DLGOpenPkr =  new wxFileDialog(this, wxT("Open PKR2 File"), wxT(""), wxT(""), wxT("*.pkr"), wxOPEN | wxFILE_MUST_EXIST);

	DLGRepFile =  new wxFileDialog(this, wxT("Replace file with"), wxT(""), wxT(""), wxT("*.*"), wxOPEN);

	BTNSavePkr = new wxButton(this, ID_BTNSAVEPKR, wxT("Save PKR File"), wxPoint(603, 0), wxSize(190, 21), 0, wxDefaultValidator, wxT("BTNSavePkr"));

	BTNOpenPkr = new wxButton(this, ID_BTNOPENPKR, wxT("Open PKR File"), wxPoint(413, 0), wxSize(189, 21), 0, wxDefaultValidator, wxT("BTNOpenPkr"));

	BTNReplaceFile = new wxButton(this, ID_BTNREPLACEFILE, wxT("Replace File"), wxPoint(184, 511), wxSize(85, 32), 0, wxDefaultValidator, wxT("BTNReplaceFile"));
	BTNReplaceFile->Enable(false);

	BTNDeleteFile = new wxButton(this, ID_BTNDELETEFILE, wxT("Delete File"), wxPoint(96, 544), wxSize(85, 28), 0, wxDefaultValidator, wxT("BTNDeleteFile"));
	BTNDeleteFile->Enable(false);

	BTNExtractFile = new wxButton(this, ID_BTNEXTRACTFILE, wxT("Export File"), wxPoint(95, 511), wxSize(87, 32), 0, wxDefaultValidator, wxT("BTNExtractFile"));
	BTNExtractFile->Enable(false);

	BTNAddFile = new wxButton(this, ID_BTNADDFILE, wxT("Import New File"), wxPoint(184, 544), wxSize(85, 28), 0, wxDefaultValidator, wxT("BTNAddFile"));
	BTNAddFile->Enable(false);

	BTNExtDir = new wxButton(this, ID_BTNEXTDIR, wxT("Extract Folder"), wxPoint(0, 554), wxSize(95, 19), 0, wxDefaultValidator, wxT("BTNExtDir"));
	BTNExtDir->Enable(false);

	BTNDelDir = new wxButton(this, ID_BTNDELDIR, wxT("Delete Folder"), wxPoint(0, 533), wxSize(95, 20), 0, wxDefaultValidator, wxT("BTNDelDir"));
	BTNDelDir->Enable(false);

	BTNAddDir = new wxButton(this, ID_EDTADDDIR, wxT("Add New Folder"), wxPoint(0, 512), wxSize(95, 20), 0, wxDefaultValidator, wxT("BTNAddDir"));

	EDTText = new wxTextCtrl(this, ID_EDTTEXT, wxT(""), wxPoint(270, 20), wxSize(522, 420), wxTE_READONLY | wxTE_MULTILINE, wxDefaultValidator, wxT("EDTText"));

	HTMLBmp = new wxHtmlWindow(this, ID_HTMLBMP, wxPoint(270, 20), wxSize(522, 420));

	EDTConsole = new wxTextCtrl(this, ID_EDTCONSOLE, wxT(""), wxPoint(270, 442), wxSize(521, 130), wxTE_READONLY | wxTE_MULTILINE, wxDefaultValidator, wxT("EDTConsole"));
	EDTConsole->SetForegroundColour(wxColour(wxT("WHITE")));
	EDTConsole->SetBackgroundColour(wxColour(wxT("BLACK")));
	EDTConsole->SetFont(wxFont(9, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Arial")));

	wxArrayString arrayStringFor_LSTFiles;
	LSTFiles = new wxListBox(this, ID_LSTFILES, wxPoint(94, 0), wxSize(175, 510), arrayStringFor_LSTFiles, wxLB_SINGLE);

	wxArrayString arrayStringFor_LSTDirs;
	LSTDirs = new wxListBox(this, ID_LSTDIRS, wxPoint(0, 0), wxSize(94, 510), arrayStringFor_LSTDirs, wxLB_SINGLE);

	SetTitle(wxT("Kamiloxnumetal's THPS2 ALL.PKR Editor"));
	SetIcon(Self_PKR2EditorFrm_XPM);
	SetSize(8,8,800,600);
	Center();
	
	////GUI Items Creation End
}

/*******************************************************************************/

void PKR2EditorFrm::OnClose(wxCloseEvent& event)
{
	Destroy();
}

/*******************************************************************************/

void PKR2EditorFrm::ClearMem()
{
    for(unsigned short y,x = 0; x < dirs_n; x++)
    {
        for(y = 0; y < dirs[x].dfiles_n; y++)
        {
            delete[] dirs[x].dfiles[y].fdata;
        }
        delete[] dirs[x].dfiles;
    }
    delete[] dirs;
    delete[] exdir;
    delete[] exfile;
    dirs = NULL;
	exdir = NULL;
	exfile = NULL;
	dirs_n = 0;
	files_n = 0;
    BTNReplaceFile -> Enable(false);
    BTNDeleteFile -> Enable(false);
    BTNExtractFile -> Enable(false);
    BTNAddFile -> Enable(false);
    BTNExtDir -> Enable(false);
    BTNDelDir -> Enable(false);
    LSTDirs -> Clear();
    LSTFiles -> Clear();
    EDTText -> Show(false);
	HTMLBmp -> Show(false);
}

/*******************************************************************************/

void PKR2EditorFrm::Print(const wxChar* text)
{
    EDTConsole -> AppendText(text);
}

/*******************************************************************************/

void PKR2EditorFrm::Print(unsigned int num)
{
    char aux[13];
    itoa(num,aux,10);
    EDTConsole -> AppendText(aux);
}

/*******************************************************************************/

void PKR2EditorFrm::MakeFileList(unsigned short index)
{
    EDTText -> Show(false);
	HTMLBmp -> Show(false);
    LSTFiles -> Clear();
    for(unsigned short x = 0; x < dirs[index].dfiles_n; x++)
    {
        LSTFiles -> Append(dirs[index].dfiles[x].fname);
    }
    LSTFiles -> SetSelection(0);
    if(dirs[index].dfiles_n == 0)
    {
        BTNReplaceFile -> Enable(false);
        BTNDeleteFile -> Enable(false);
        BTNExtractFile -> Enable(false);
    }         
    else
    {
        BTNReplaceFile -> Enable();
        BTNDeleteFile -> Enable();
        BTNExtractFile -> Enable();
    }            
}

/*******************************************************************************/

unsigned short PKR2EditorFrm::GetExtension(char* text)
{
    Str = text;
    Str = Str.SubString(Str.Length() - 3,Str.Length() - 1);
    if(Str == "WAV")
        return 1;
    else if(Str == "BMP")
        return 2;
    else if(Str == "TXT")
        return 3;
    else
        return 0;
}

/*******************************************************************************/

void PKR2EditorFrm::LoadBMP()
{
    FHandler.Open("Temp.Bmp",wxFile::write);
    FHandler.Write(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata,dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fsize);
    FHandler.Close();
    HTMLBmp -> SetPage("<HMTL><BODY Bgcolor=\"Grey\"><IMG Src=\"Temp.bmp\"></IMG></BODY></HTML>");
    HTMLBmp -> Show();
}

/*******************************************************************************/

void PKR2EditorFrm::LoadTXT()
{
    EDTText -> SetValue((char*)dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata);
    EDTText -> Show();
}

/*******************************************************************************/

void PKR2EditorFrm::LoadWAV()
{
    FHandler.Open("Temp.Wav",wxFile::write);
    FHandler.Write(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata,dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fsize);
    FHandler.Close();
    PlaySound((LPCSTR)"Temp.Wav", NULL, SND_FILENAME | SND_ASYNC); 
}

/*******************************************************************************/

void PKR2EditorFrm::LSTDirsSelected(wxCommandEvent& event)
{
	MakeFileList(LSTDirs -> GetSelection());
}

/*******************************************************************************/

void PKR2EditorFrm::BTNOpenPkrClick(wxCommandEvent& event)
{
	if(DLGOpenPkr -> ShowModal() == wxID_OK)
	{
        ClearMem();
        EDTConsole -> SetValue("");
        Print("Reading file: ");Print(DLGOpenPkr -> GetPath());
        if(FHandler.Open(DLGOpenPkr -> GetPath(),wxFile::read))
        {
            FHandler.Read(pkrheader,4); // Read PKR2 Header
            pkrheader[4] = '\0';
            Str = pkrheader;
            if(Str == "PKR2")
            {
                FHandler.Read(&aux,4);    // Second u_int 0x00000001 ?
                Print("\nReading master header...");
                FHandler.Read(&dirs_n,4); // Number of folders
                Print(", Found ");Print(dirs_n);Print(" folders");
                FHandler.Read(&files_n,4);// Number of all files
                Print(", Found ");Print(files_n);Print(" files");
                if(dirs_n > 0)
                {
                    dirs = new dirheader[dirs_n]; // Dir container
                    for(unsigned short x = 0; x < dirs_n; x++) // Read Dirs Headers
                    {
                        Print("\nReading folder header: ");
                        FHandler.Read(dirs[x].dname,32); // Read Dir Name
                        Print(dirs[x].dname);
                        FHandler.Read(&aux,4);  // Read File Headers Offset (null)
                        FHandler.Read(&(dirs[x].dfiles_n),4); // Read Files In Folder
                        if(dirs[x].dfiles_n > 0)
                            dirs[x].dfiles = new fileheader[dirs[x].dfiles_n];
                        else
                            dirs[x].dfiles = NULL;
                        Print(", Found ");Print(dirs[x].dfiles_n);Print(" files");
                        LSTDirs -> Append(dirs[x].dname);
                    }
                    LSTDirs -> SetSelection(0);
                    if(files_n > 0)
                    {
                        Print("\nReading file headers...");
                        for(unsigned short y,x = 0; x < dirs_n; x++) // Read File Headers
                        {
                            for(y = 0; y < dirs[x].dfiles_n; y++)
                            {
                                FHandler.Read(dirs[x].dfiles[y].fname,32); // Read File Name
                                FHandler.Read(&aux,4); // Read 0xfffffffe u_int ? (null)
                                FHandler.Read(&aux,4); // Read Offset (null)
                                FHandler.Read(&aux,4); // Read Uncompressed Size (null)
                                FHandler.Read(&(dirs[x].dfiles[y].fsize),4); // Read compressed Size
                                dirs[x].dfiles[y].fdata = new unsigned char[dirs[x].dfiles[y].fsize];
                            }
                        }
                        MakeFileList(0);
                        Print("\nReading file data...");
                        for(unsigned short y,x = 0; x < dirs_n; x++) // Read File Data
                        {
                            for(y = 0; y < dirs[x].dfiles_n; y++)
                            {
                                FHandler.Read(dirs[x].dfiles[y].fdata,dirs[x].dfiles[y].fsize);
                            }
                        }
                        Print("\nFile readed and loaded to memory!");
                    }
                }
                if(dirs_n > 0)
                {
                    BTNExtDir -> Enable();
                    BTNDelDir -> Enable();
                    if(dirs[0].dfiles_n > 0)
                    {
                        BTNReplaceFile -> Enable();
                        BTNDeleteFile -> Enable();
                        BTNExtractFile -> Enable();
                        BTNAddFile -> Enable();
                    }
                }
            }
            else
            {
                Print("\nFile: ");
                Print(DLGOpenPkr -> GetPath());
                Print(" isn't a PKR2 file");
            }
            FHandler.Close();
        }
        else
            FHandler.Close();
    }
}

/*******************************************************************************/

void PKR2EditorFrm::LSTFilesDoubleClicked(wxCommandEvent& event)
{
    EDTText -> Show(false);
	HTMLBmp -> Show(false);
	switch(GetExtension(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fname))
	{
        case 1: LoadWAV(); break;
        case 2: LoadBMP(); break;
        case 3: LoadTXT(); break;
    }
}

/*******************************************************************************/

void PKR2EditorFrm::LSTFilesSelected(wxCommandEvent& event)
{
    EDTText -> Show(false);
	HTMLBmp -> Show(false);
	switch(GetExtension(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fname))
	{
        case 1: LoadWAV(); break;
        case 2: LoadBMP(); break;
        case 3: LoadTXT(); break;
    }
}

/*******************************************************************************/

void PKR2EditorFrm::BTNExtractFileClick(wxCommandEvent& event)
{
	DLGExtFile -> SetFilename(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fname);
	if(DLGExtFile -> ShowModal() == wxID_OK)
	{
        if(FHandler.Open(DLGExtFile -> GetPath(),wxFile::write))
        {
            FHandler.Write(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata,dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fsize);
            FHandler.Close();
            Print("\nFile: ");Print(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fname);Print(" Saved To: ");Print(DLGExtFile -> GetPath());
        }
        else
        {
            Print("\nDestination file is used by other program...");
            FHandler.Close();
        }
    }
}

/*******************************************************************************/

void PKR2EditorFrm::BTNReplaceFileClick(wxCommandEvent& event)
{
	if(DLGRepFile -> ShowModal() == wxID_OK)
	{
        if(FHandler.Open(DLGRepFile -> GetPath(),wxFile::read))
        {
            delete[] dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata;
            dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata = NULL;
            dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fsize = FHandler.Length();
            dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata = new unsigned char[dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fsize];
            FHandler.Read(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fdata,dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fsize);
            FHandler.Close();
            Print("\nFile: ");Print(dirs[LSTDirs -> GetSelection()].dfiles[LSTFiles -> GetSelection()].fname);Print(" Replaced with: ");Print(DLGRepFile -> GetPath());
        }
        else
        {
            Print("\nCan't open source file...");
            FHandler.Close();
        }
    }
}

/*******************************************************************************/

void PKR2EditorFrm::BTNDeleteFileClick(wxCommandEvent& event)
{
    unsigned short indexf = LSTFiles -> GetSelection();
    unsigned short indexd = LSTDirs -> GetSelection();
	Print("\nDeleting File: ");Print(dirs[indexd].dfiles[indexf].fname);Print(", Please Wait...");
	exfile = dirs[indexd].dfiles;
	if(dirs[indexd].dfiles_n - 1 > 0)
	{
	   dirs[indexd].dfiles = new fileheader[dirs[indexd].dfiles_n - 1];
	   for(unsigned short y,x = 0; x < dirs[indexd].dfiles_n; x++)
	   {
            y = x;
            if(x == indexf)
            {
                delete exfile[x].fdata;
                exfile[x].fdata = NULL;
                continue;
            }
            else if(x > indexf)
            {
                y--;
            }
            strcpy(dirs[indexd].dfiles[y].fname,exfile[x].fname);
            dirs[indexd].dfiles[y].fsize = exfile[x].fsize;
            dirs[indexd].dfiles[y].fdata = exfile[x].fdata;
        }
    }
    else
        dirs[indexd].dfiles = NULL;
    delete[] exfile;
    exfile = NULL;
	dirs[indexd].dfiles_n--;
	files_n--;
	MakeFileList(LSTDirs -> GetSelection());
	Print(", File Deleted!");
}

/*******************************************************************************/

void PKR2EditorFrm::BTNAddFileClick(wxCommandEvent& event)
{
    bool nsizeok = false;
    bool okpush = false;
    if(DLGAddFile -> ShowModal() == wxID_OK)
    {
        DLGFileName -> SetValue(DLGAddFile -> GetFilename());
        filenamecheck:
        if(DLGFileName -> ShowModal() == wxID_OK)
        {
            okpush = true;
            if(DLGFileName -> GetValue().Length() > 0 && DLGFileName -> GetValue().Length() < 32)
                nsizeok = true;
        }
        else
            okpush = false;
        if(!nsizeok && okpush)
        {
            DLGNameInvalid -> ShowModal();
            goto filenamecheck;
        }
    }
    if(okpush)
    {
        unsigned short indexd = LSTDirs -> GetSelection();
        Print("\nAdding file: ");Print(DLGAddFile -> GetPath());Print(" as: ");Print(DLGFileName -> GetValue().MakeUpper());Print(" Please wait...");
	    if(FHandler.Open(DLGAddFile -> GetPath(),wxFile::read))
	    {
           exfile = dirs[indexd].dfiles;
    	   dirs[indexd].dfiles_n++;
	       dirs[indexd].dfiles = new fileheader[dirs[indexd].dfiles_n];
	       for(unsigned short x = 0; x < dirs[indexd].dfiles_n - 1; x++)
	       {
                strcpy(dirs[indexd].dfiles[x].fname,exfile[x].fname);
                dirs[indexd].dfiles[x].fsize = exfile[x].fsize;
                dirs[indexd].dfiles[x].fdata = exfile[x].fdata;
           }
            delete[] exfile;
            exfile = NULL;
            strcpy(dirs[indexd].dfiles[dirs[indexd].dfiles_n - 1].fname,(const char*)DLGFileName -> GetValue().MakeUpper());
            dirs[indexd].dfiles[dirs[indexd].dfiles_n - 1].fsize = FHandler.Length();
            dirs[indexd].dfiles[dirs[indexd].dfiles_n - 1].fdata = new unsigned char[dirs[indexd].dfiles[dirs[indexd].dfiles_n - 1].fsize];
            FHandler.Read(dirs[indexd].dfiles[dirs[indexd].dfiles_n - 1].fdata,dirs[indexd].dfiles[dirs[indexd].dfiles_n - 1].fsize);
            FHandler.Close();   
	        files_n++;
	        MakeFileList(LSTDirs -> GetSelection());
	        Print(", File Added Succesfully!");
        }
        else
        {
            Print("\nCan't open source file...");
            FHandler.Close();
        }
    }
}

/*******************************************************************************/

void PKR2EditorFrm::BTNNewPkrClick(wxCommandEvent& event)
{
	ClearMem();
    EDTConsole -> SetValue("");
}

/*******************************************************************************/

void PKR2EditorFrm::BTNDelDirClick(wxCommandEvent& event)
{
	unsigned short indexd = LSTDirs -> GetSelection();
	Print("\nDeleting Folder: ");Print(dirs[indexd].dname);Print(" Please wait...");
    for(unsigned short z = 0; z < dirs[indexd].dfiles_n; z++)
    {
        delete[] dirs[indexd].dfiles[z].fdata;
        dirs[indexd].dfiles[z].fdata = NULL;
    }
    delete[] dirs[indexd].dfiles;
    dirs[indexd].dfiles = NULL;
    exdir = dirs;
    LSTDirs -> Clear();
    LSTFiles -> Clear();
    if(dirs_n - 1 > 0)
    {
        dirs = new dirheader[dirs_n - 1];
        for(unsigned short y,x = 0; x < dirs_n; x++)
        {
            y = x;
            if(x == indexd)
            {
                delete dirs[x].dfiles;
                dirs[x].dfiles = NULL;
                continue;
            }
            else if(x > indexd)
            {
                y--;
            }
            strcpy(dirs[y].dname,exdir[x].dname);
            dirs[y].dfiles_n = exdir[x].dfiles_n;
            dirs[y].dfiles = exdir[x].dfiles;  
            LSTDirs -> Append(dirs[y].dname);
        }
        LSTDirs -> SetSelection(0);
        MakeFileList(0);
    }       
    else
    {
        EDTText -> Show(false);
	    HTMLBmp -> Show(false);
	    BTNReplaceFile -> Enable(false);
        BTNDeleteFile -> Enable(false);
        BTNExtractFile -> Enable(false);
        BTNAddFile -> Enable(false);
        BTNExtDir -> Enable(false);
        BTNDelDir -> Enable(false);
        dirs = NULL;
    }
    delete[] exdir;
    exdir = NULL;
    dirs_n--;
    Print(" , Folder deleted!");
}

/*******************************************************************************/


void PKR2EditorFrm::BTNAddDirClick(wxCommandEvent& event)
{
    bool nsizeok = false;
    bool okpush = false;
    foldernamecheck:
    if(DLGFolderName -> ShowModal() == wxID_OK)
    {
        okpush = true;
        if(DLGFolderName -> GetValue().Length() > 0 && DLGFolderName -> GetValue().Length() < 32)
            nsizeok = true;
    }
    else
        okpush = false;
    if(!nsizeok && okpush)
    {
        DLGNameInvalid -> ShowModal();
        goto foldernamecheck;
    }
    if(okpush)
    {
        Print("\nAdding folder: ");Print(DLGFolderName -> GetValue());Print(" Please wait...");
	    exdir = dirs;
	    dirs_n++;
	    dirs = new dirheader[dirs_n];
	    for(unsigned short x = 0; x < dirs_n - 1; x++)
	    {
            strcpy(dirs[x].dname,exdir[x].dname);
            dirs[x].dfiles_n = exdir[x].dfiles_n;
            dirs[x].dfiles = exdir[x].dfiles;
        }
        delete[] exdir;
        exdir = NULL;
        strcpy(dirs[dirs_n-1].dname,(const char*)DLGFolderName -> GetValue());
        dirs[dirs_n-1].dfiles_n = 0;
        dirs[dirs_n-1].dfiles = NULL;
        LSTDirs -> Append(dirs[dirs_n-1].dname);
        BTNAddFile -> Enable();
        BTNExtDir -> Enable();
        BTNDelDir -> Enable();
        LSTDirs -> SetSelection(0);
        MakeFileList(0);
	    Print(", Folder Added Succesfully!");
    }
}

/*******************************************************************************/

void PKR2EditorFrm::BTNExtDirClick(wxCommandEvent& event)
{
	if(DLGExtFolder -> ShowModal() == wxID_OK)
	{
        Print("\nExporting Folder: ");Print(dirs[LSTDirs -> GetSelection()].dname);Print(" to ");Print(DLGExtFolder -> GetPath());
        for(unsigned short x = 0; x < dirs[LSTDirs -> GetSelection()].dfiles_n; x++)
        {
            Str = DLGExtFolder -> GetPath();
            Str += "/";
            Str += dirs[LSTDirs -> GetSelection()].dfiles[x].fname;
            if(FHandler.Open(Str,wxFile::write))
            {
                FHandler.Write(dirs[LSTDirs -> GetSelection()].dfiles[x].fdata,dirs[LSTDirs -> GetSelection()].dfiles[x].fsize);
                FHandler.Close();
            }
            else
            {
                Print("\nWarning! File: ");Print(dirs[LSTDirs -> GetSelection()].dfiles[x].fname);Print(" is used by other program...");
                FHandler.Close();
            }
        }
        Print("\nFolder exported!");
    }
}

/*******************************************************************************/

void PKR2EditorFrm::BTNSavePkrClick(wxCommandEvent& event)
{
	if(DLGSavePkr -> ShowModal() == wxID_OK)
	{
        Print("\nSaving PKR2 to: ");Print(DLGSavePkr -> GetPath());Print(" Please Wait...");
        if(FHandler.Open(DLGSavePkr -> GetPath(),wxFile::write))
        {
            unsigned int offset = 0; 
            Print("\nWriting master header");
            // Main Header
            strcpy(pkrheader,"PKR2");
            FHandler.Write(pkrheader,4); // PKR2 Header
            aux = 0x0000001;   
            FHandler.Write(&aux,4); // 0x00000001?
            FHandler.Write(&dirs_n,4); // Total dirs
            FHandler.Write(&files_n,4); // Total files
            offset += 16; // + Master Header Size 16 Bytes
            Print("\nWriting folder header");
            // Directory Header
            offset += 40*dirs_n; // + Directory Header Size 40 bytes per Directory
            for(unsigned short x = 0; x < dirs_n; x++)
            {
                FHandler.Write(dirs[x].dname,32); // Folder name
                FHandler.Write(&offset,4); // File headers offset
                FHandler.Write(&(dirs[x].dfiles_n),4); // Total files in folder
                offset += 48*dirs[x].dfiles_n; // + File Header Size 48 bytes per File in this Dir
            }
            aux = 0xfffffffe;
            Print("\nWriting file headers");
            // File Header
            for(unsigned short y,x = 0; x < dirs_n; x++)
            {
                for(y = 0; y < dirs[x].dfiles_n; y++)
                {
                    FHandler.Write(dirs[x].dfiles[y].fname,32); // File name
                    FHandler.Write(&aux,4); // 0xfffffffe?
                    FHandler.Write(&offset,4); // File data offset
                    FHandler.Write(&(dirs[x].dfiles[y].fsize),4); // Uncompressed Size, THPS don't use compression U.Size == C.Size
                    FHandler.Write(&(dirs[x].dfiles[y].fsize),4); // Compressed Size
                    offset += dirs[x].dfiles[y].fsize;
                }
            }
            Print("\nWriting ");Print(offset - 40*dirs_n - 48*files_n - 16);Print(" bytes of file data, Wait...");
            // File Data
            for(unsigned short y,x = 0; x < dirs_n; x++)
            {
                for(y = 0; y < dirs[x].dfiles_n; y++)
                {
                    FHandler.Write(dirs[x].dfiles[y].fdata,dirs[x].dfiles[y].fsize);
                }
            }
            Print("\nFile Saved Succesfully!");
        }
        else
        {
            Print("\nDestination file is used by other program...");
        }
        FHandler.Close();
    }
}
