/*******************************************************************************/
#include "PKRRepackFrm.h"

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

////Header Include Start
#include "Images/Self_PKRRepackFrm_XPM.xpm"
////Header Include End

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

////Event Table Start
BEGIN_EVENT_TABLE(PKRRepackFrm,wxFrame)
	////Manual Code Start
	////Manual Code End
	
	EVT_CLOSE(PKRRepackFrm::OnClose)
	EVT_BUTTON(ID_BTNPLAYWAV,PKRRepackFrm::BTNPlayWavClick)
	EVT_BUTTON(ID_BTNSAVEALL,PKRRepackFrm::BTNSaveAllClick)
	EVT_BUTTON(ID_BTNREPLACE,PKRRepackFrm::BTNReplaceClick)
	EVT_BUTTON(ID_BTNEXTRACTFILE,PKRRepackFrm::BTNExtractFileClick)
	EVT_LISTBOX(ID_LSTFILES,PKRRepackFrm::LSTFilesSelected)
	EVT_LISTBOX_DCLICK(ID_LSTFILES,PKRRepackFrm::LSTFilesDoubleClicked)
END_EVENT_TABLE()
////Event Table End

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

PKRRepackFrm::PKRRepackFrm(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
: wxFrame(parent, id, title, position, size, style)
{
	CreateGUIControls();
	Allpkr = new wxFile();
	Outpkr = new wxFile();
	for(short x = 0; x < 3771; x++)
	{
        files[x].data = NULL;   
    }
    FileViewer -> SetBorders(0);
    FileViewer -> Show(false);
    TextViewer -> Show(false);
	if(Allpkr -> Open("ALL.PKR",wxFile::read))
	{
        EDTConsole -> SetValue("Reading \"ALL.PKR\"...");
	    EDTConsole -> AppendText("\nReading directory header...");
	    Allpkr -> Read(&dirinfo[0],856);
	    EDTConsole -> AppendText("\n856 bytes directory header readed ok!");
	    offset = 856;      // bytes de info de directorios
	    EDTConsole -> AppendText("\nReading file header...");
	    for(short x = 0; x < 3771; x++)
	    {
            Allpkr -> Read(&(files[x].name[0]),32); // Filename
            Allpkr -> Read(&aux,4);              // 0xfffffffe ???
            Allpkr -> Read(&aux,4);              // Offset, se ignora ya que luego cambiara;
            Allpkr -> Read(&(files[x].size),4); // Uncompressed size
            Allpkr -> Read(&aux,4);              // Compressed size == Usize ignorado
            offset += 48; // bytes de info de archivos (lo que se leera)
        }
        EDTConsole -> AppendText("\n3771 - 48 bytes file headers readed ok!");
        EDTConsole -> AppendText("\nReading file data...");
        wxString dir("Audio/");
        wxString path("");
        for(short x = 0; x < 3771; x++)
        {
            files[x].data = new unsigned char[files[x].size];
            Allpkr -> Read(files[x].data,files[x].size);
            switch(x)
            {
                case 312:  dir = "data/"; break;
                case 1462: dir = "data/logos/"; break;
                case 1747: dir = "data/lti/"; break;
                case 1770: dir = "data/skatedit/"; break;
                case 2094: dir = "newbmp/"; break;
                case 2313: dir = "newtxt/"; break;
                case 2354: dir = "newtxt/Bullring/"; break;
                case 2461: dir = "newtxt/Ed1/"; break;
                case 2532: dir = "newtxt/Ed2/"; break;
                case 2583: dir = "newtxt/Ed3/"; break;
                case 2628: dir = "newtxt/Ed4/"; break;
                case 2681: dir = "newtxt/Hangar/"; break;
                case 2756: dir = "newtxt/Hawaii/"; break;
                case 2812: dir = "newtxt/Heaven/"; break;
                case 2905: dir = "newtxt/Mar/"; break;
                case 3069: dir = "newtxt/NY/"; break;
                case 3180: dir = "newtxt/Philly/"; break;
                case 3320: dir = "newtxt/School2/"; break;
                case 3517: dir = "newtxt/SS/"; break;
                case 3622: dir = "newtxt/Venice/"; break;
            }
            path = dir;
            path += files[x].name;
            LSTFiles -> Append(path);
        }
        LSTFiles -> SetSelection(0);
        EDTConsole -> AppendText("\nFile data readed ok!");
	    EDTConsole -> AppendText("\n\"ALL.PKR\" Successfully readed and loaded!\n");
    }
    else
    {
        BTNExtractFile -> Enable(false);
        BTNReplace -> Enable(false);
        BTNSaveAll -> Enable(false);
        BTNPlayWav -> Enable(false);
        EDTConsole -> SetValue("\"ALL.PKR\" Not Found, Put \"ALL.PKR\" in the program directory and restart the program.");
    }
}

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

PKRRepackFrm::~PKRRepackFrm()
{
    Allpkr -> ~wxFile(); // Cierra ALL.PKR y libera el puntero
    Outpkr -> ~wxFile();
    for(short x = 0; x < 3771; x++)
	{
        delete[] files[x].data;   
    }
}

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

void PKRRepackFrm::CreateGUIControls()
{
	//Do not add custom code between
	//GUI Items Creation Start and GUI Items Creation End
	//wxDev-C++ designer will remove them.
	//Add the custom code before or after the blocks
	////GUI Items Creation Start

	TextViewer = new wxTextCtrl(this, ID_TEXTVIEWER, wxT(""), wxPoint(321, 33), wxSize(470, 391), wxTE_READONLY | wxTE_MULTILINE, wxDefaultValidator, wxT("TextViewer"));

	FileViewer = new wxHtmlWindow(this, ID_FILEVIEWER, wxPoint(320, 31), wxSize(474, 394));

	BTNPlayWav = new wxButton(this, ID_BTNPLAYWAV, wxT("Play *.WAV File"), wxPoint(319, 426), wxSize(473, 28), 0, wxDefaultValidator, wxT("BTNPlayWav"));

	DLGExtract =  new wxFileDialog(this, wxT("Choose file name"), wxT(""), wxT(""), wxT("*.*"), wxSAVE);

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

	BTNSaveAll = new wxButton(this, ID_BTNSAVEALL, wxT("Save All To OUT.PKR"), wxPoint(557, 1), wxSize(229, 28), 0, wxDefaultValidator, wxT("BTNSaveAll"));

	BTNReplace = new wxButton(this, ID_BTNREPLACE, wxT("Replace File"), wxPoint(444, 1), wxSize(107, 28), 0, wxDefaultValidator, wxT("BTNReplace"));

	BTNExtractFile = new wxButton(this, ID_BTNEXTRACTFILE, wxT("Extract File"), wxPoint(321, 1), wxSize(118, 28), 0, wxDefaultValidator, wxT("BTNExtractFile"));

	EDTConsole = new wxTextCtrl(this, ID_EDTCONSOLE, wxT(""), wxPoint(320, 453), wxSize(473, 120), wxTE_READONLY | wxTE_MULTILINE, wxDefaultValidator, wxT("EDTConsole"));
	EDTConsole->SetForegroundColour(wxColour(wxT("WHITE")));
	EDTConsole->SetBackgroundColour(wxColour(wxT("BLACK")));

	wxArrayString arrayStringFor_LSTFiles;
	LSTFiles = new wxListBox(this, ID_LSTFILES, wxPoint(0, 0), wxSize(320, 574), arrayStringFor_LSTFiles, wxLB_SINGLE);

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

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

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

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

void PKRRepackFrm::BTNExtractFileClick(wxCommandEvent& event)
{
    DLGExtract -> SetFilename(files[LSTFiles -> GetSelection()].name);
	if(DLGExtract -> ShowModal() == wxID_OK)
	{
        Outpkr -> Open(DLGExtract -> GetPath(),wxFile::write);
        Outpkr -> Write(files[LSTFiles -> GetSelection()].data,files[LSTFiles -> GetSelection()].size);
        Outpkr -> Close();
        EDTConsole -> AppendText("\nFile: ");
        EDTConsole -> AppendText(files[LSTFiles -> GetSelection()].name);
        EDTConsole -> AppendText(" extracted.");
    }
}

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

void PKRRepackFrm::BTNReplaceClick(wxCommandEvent& event)
{
	if(DLGReplace -> ShowModal() == wxID_OK)
	{
        Outpkr -> Open(DLGReplace -> GetPath(),wxFile::read);
        files[LSTFiles -> GetSelection()].size = Outpkr -> Length();
        delete[] files[LSTFiles -> GetSelection()].data;
        files[LSTFiles -> GetSelection()].data = new unsigned char[files[LSTFiles -> GetSelection()].size];
        Outpkr -> Read(files[LSTFiles -> GetSelection()].data,files[LSTFiles -> GetSelection()].size);
        Outpkr -> Close();
        EDTConsole -> AppendText("\nFile: ");
        EDTConsole -> AppendText(files[LSTFiles -> GetSelection()].name);
        EDTConsole -> AppendText(" replaced\nUse \"Save All to OUT.PKR\" to save your changes.");
        wxString name(files[LSTFiles -> GetSelection()].name);
        if(name.SubString(name.Length() - 3,name.Length() - 1) == "BMP")
        {
            Outpkr -> Open("Temp.Bmp",wxFile::write);
            Outpkr -> Write(files[LSTFiles -> GetSelection()].data,files[LSTFiles -> GetSelection()].size);
            Outpkr -> Close();
            FileViewer -> Show(true);
            TextViewer -> Show(false);
            FileViewer -> SetPage("<HTML><BODY><IMG SRC=\"Temp.Bmp\"></IMG></BODY></HTML>");
        }
        else if(name.SubString(name.Length() - 3,name.Length() - 1) == "TXT")
        {
            FileViewer -> Show(false);
            TextViewer -> Show(true);
            TextViewer -> SetValue((char*) files[LSTFiles -> GetSelection()].data);
        }
        else
        {
            FileViewer -> Show(false);
            TextViewer -> Show(false);
        }
    }
}

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

void PKRRepackFrm::BTNSaveAllClick(wxCommandEvent& event)
{
    BTNExtractFile -> Enable(false);
    BTNReplace -> Enable(false);
    BTNSaveAll -> Enable(false);
    unsigned int offset2 = offset;
    EDTConsole -> AppendText("\n\nWriting \"OUT.PKR\"...");
	Outpkr -> Open("OUT.PKR",wxFile::write);
	EDTConsole -> AppendText("\nWriting 856 bytes of directory header...");
	Outpkr -> Write(&dirinfo[0],856);
    EDTConsole -> AppendText("\nWriting 181008 bytes of files headers...");
	aux = 0xfffffffe;
	for(short x = 0; x < 3771; x++)
	{
        Outpkr -> Write(&(files[x].name[0]),32); // Filename
        Outpkr -> Write(&aux,4); // 0xfffffffe ???
        Outpkr -> Write(&offset2,4); // Offset
        offset2 += files[x].size;
        Outpkr -> Write(&(files[x].size),4); // Uncompressed size
        Outpkr -> Write(&(files[x].size),4); // Compressed size == Usize ignorado
    }
	EDTConsole -> AppendText("\nWriting files...");
	for(short x = 0; x < 3771; x++)
	{
        Outpkr -> Write(files[x].data,files[x].size); // Filename
    }
	Outpkr -> Close();
	BTNExtractFile -> Enable(true);
    BTNReplace -> Enable(true);
    BTNSaveAll -> Enable(true);
    EDTConsole -> AppendText("\n\"OUT.PKR\" writed successfully!\n");
}

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

void PKRRepackFrm::LSTFilesSelected(wxCommandEvent& event)
{
    wxString name(files[LSTFiles -> GetSelection()].name);
    BTNPlayWav -> Enable(name.SubString(name.Length() - 3,name.Length() - 1) == "WAV");
    if(name.SubString(name.Length() - 3,name.Length() - 1) == "BMP")
    {
        Outpkr -> Open("Temp.Bmp",wxFile::write);
        Outpkr -> Write(files[LSTFiles -> GetSelection()].data,files[LSTFiles -> GetSelection()].size);
        Outpkr -> Close();
        FileViewer -> Show(true);
        TextViewer -> Show(false);
        FileViewer -> SetPage("<HTML><BODY><IMG SRC=\"Temp.Bmp\"></IMG></BODY></HTML>");
    }
    else if(name.SubString(name.Length() - 3,name.Length() - 1) == "TXT")
    {
        FileViewer -> Show(false);
        TextViewer -> Show(true);
        TextViewer -> SetValue((char*) files[LSTFiles -> GetSelection()].data);
    }
    else
    {
        FileViewer -> Show(false);
        TextViewer -> Show(false);
    }
}

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

void PKRRepackFrm::BTNPlayWavClick(wxCommandEvent& event)
{
    Outpkr -> Open("Temp.Wav",wxFile::write);
    Outpkr -> Write(files[LSTFiles -> GetSelection()].data,files[LSTFiles -> GetSelection()].size);
    Outpkr -> Close();
	PlaySound((LPCSTR)"Temp.Wav", NULL, SND_FILENAME | SND_ASYNC); 
}

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

void PKRRepackFrm::LSTFilesDoubleClicked(wxCommandEvent& event)
{
    wxString name(files[LSTFiles -> GetSelection()].name);
	if(name.SubString(name.Length() - 3,name.Length() - 1) == "WAV")
	{
        Outpkr -> Open("Temp.Wav",wxFile::write);
        Outpkr -> Write(files[LSTFiles -> GetSelection()].data,files[LSTFiles -> GetSelection()].size);
        Outpkr -> Close();
	    PlaySound((LPCSTR)"Temp.Wav", NULL, SND_FILENAME | SND_ASYNC); 
    }
}

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