/***************************************************************
 * Name:      qcopyMain.cpp
 * Purpose:   Code for Application Frame
 * Author:    Qumbetlian (qumbetlian@yahoo.com)
 * Created:   2007-09-20
 * Copyright: Qumbetlian (www.qumbetlian.3x.ro)
 * License:   GPL
 **************************************************************/

#include "copyThread.h"
#include "Qumbetlian.xpm"
#include <wx/msgdlg.h>

//(*InternalHeaders(WFExistDialog)
#include <wx/artprov.h>
#include <wx/bitmap.h>

//(*InternalHeaders(qcopyDialog)
#include <wx/font.h>
#include <wx/fontenum.h>
#include <wx/fontmap.h>
#include <wx/image.h>
#include <wx/intl.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/filedlg.h>
#include <wx/dcclient.h>
#include <wx/icon.h>
//*)

#if defined __WXMSW__
#   include <dirent.h>
#   include <windows.h>
#   include <winuser.h>
#endif

//helper functions
enum wxbuildinfoformat {
    short_f, long_f };

wxString wxbuildinfo(wxbuildinfoformat format)
{
    wxString wxbuild(wxVERSION_STRING);

    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("-Windows");
#elif defined(__UNIX__)
        wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }

    return wxbuild;
}

BEGIN_EVENT_TABLE(qcopyDialog,wxDialog)
    //(*EventTable(qcopyDialog)
    //EVT_GAUGE_FILLING_CHANGE(wxID_ANY, qcopyDialog::OnGaugeFilling)
    //*)
END_EVENT_TABLE()

WFExistDialog::WFExistDialog(wxWindow* parent, char* fileName, wxWindowID ID)
{
    //(*IdInit(WFExistDialog)
    static const long ID_STATICTEXT = wxNewId();
    static const long ID_CONTINUE = wxNewId();
    static const long ID_OVERWRITE = wxNewId();
    static const long ID_STATICBITMAP1 = wxNewId();
	//(*Initialize(WFExistDialog)
	Create(parent, ID, _("Warning!"), wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP|wxCAPTION|wxSYSTEM_MENU, _T("ID"));
	SetClientSize(wxSize(442,128));
	StaticText = new wxStaticText(this, ID_STATICTEXT, wxString::Format(_("The file \'%s\' already exist.\nWhat do you want to do\?"), fileName), wxPoint(56,8), wxSize(376,72), wxALIGN_CENTRE, _T("ID_STATICTEXT"));
	Continue = new wxButton(this, ID_CONTINUE, _("Continue copying"), wxPoint(48,88), wxSize(128,30), 0, wxDefaultValidator, _T("ID_CONTINUE"));
	Continue->SetDefault();
	Overwrite = new wxButton(this, ID_OVERWRITE, _("Overwrite file"), wxPoint(264,88), wxSize(128,30), 0, wxDefaultValidator, _T("ID_OVERWRITE"));
	StaticBitmap1 = new wxStaticBitmap(this, ID_STATICBITMAP1, wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(_T("wxART_WARNING")),wxART_OTHER,wxSize(40,40)), wxPoint(8,8), wxSize(40,40), 0, _T("ID_STATICBITMAP1"));
	Center();
	Connect(ID_CONTINUE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler
        (WFExistDialog::OnContinue));
    Connect(ID_OVERWRITE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler
        (WFExistDialog::OnOverwrite));
	//*)
}

WFExistDialog::~WFExistDialog()
{
	//(*Destroy(WFExistDialog)
	//*)
}

void WFExistDialog::OnContinue(wxCommandEvent& event)
{
    EndModal(CONTINUECOPY);
}

void WFExistDialog::OnOverwrite(wxCommandEvent& event)
{
    EndModal(OVERWRITE);
}

qcopyDialog::qcopyDialog(wxWindow* parent,wxWindowID id)
{
    //(*Initialize(UserVariables)
    srcFileName = NULL;
    destFileName = NULL;
    //(*Initialize(UserObjects)
    semaphore1 = new wxSemaphore(0, 1);
    //(*IdInit(qcopyDialog)
    const long ID_PANEL1 = wxNewId();
    const long ID_GAUGE1 = wxNewId();
    const long ID_STATICTEXT1 = wxNewId();
    const long ID_STATICTEXT2 = wxNewId();
    const long ID_COPY = wxNewId();
    const long ID_STATICTEXT3 = wxNewId();
    const long ID_SPINCTRL = wxNewId();
    const long ID_CANCEL = wxNewId();
    const long ID_TEXTCTRLSRC = wxNewId();
    const long ID_CHOICESRC = wxNewId();
    const long ID_TEXTCTRLDEST = wxNewId();
    const long ID_CHOICEDEST = wxNewId();
    const long ID_ABOUT = wxNewId();
    //(*Initialize(qcopyDialog)
    qcopyDialog_ = this;
    Create(parent, wxID_ANY, _("Qcopy"), wxDefaultPosition, wxDefaultSize, wxCAPTION|wxSYSTEM_MENU|wxMINIMIZE_BOX|wxCLOSE_BOX, _T("wxID_ANY"));
    wxIcon icon(Qumbetlian_xpm);
    if(icon.Ok()) SetIcon(icon);
    SetClientSize(wxSize(342,110));
    BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
    Panel1 = new wxPanel(this, ID_PANEL1, wxDefaultPosition, wxSize(350,94), wxTAB_TRAVERSAL, _T("ID_PANEL1"));
    Panel1->SetMaxSize(wxSize(-1,-1));
    Gauge1 = new wxGauge(Panel1, ID_GAUGE1, 100, wxPoint(0,120), wxSize(432,24), wxGA_SMOOTH, wxDefaultValidator, _T("ID_GAUGE1"));
    StaticText1 = new wxStaticText(Panel1, ID_STATICTEXT1, _("Source file"), wxPoint(8,8), wxSize(104,24), 0, _T("ID_STATICTEXT1"));
    StaticText2 = new wxStaticText(Panel1, ID_STATICTEXT2, _("Destination file"), wxPoint(8,40), wxSize(104,23), 0, _T("ID_STATICTEXT2"));
    Copy = new wxButton(Panel1, ID_COPY, _("Copy"), wxPoint(200,80), wxSize(64,24), 0, wxDefaultValidator, _T("ID_COPY"));
    Copy->SetToolTip(_("Start copy of source file to destination file"));
    StaticText3 = new wxStaticText(Panel1, ID_STATICTEXT3, _("Resolution"), wxPoint(8,80), wxSize(104,24), 0, _T("ID_STATICTEXT3"));
    SpinCtrl = new wxSpinCtrl(Panel1, ID_SPINCTRL, _T("256"), wxPoint(120,80), wxSize(64,23), 0, 2, 2048, 256, _T("ID_SPINCTRL"));
    SpinCtrl->SetValue(_T("256"));
    SpinCtrl->SetToolTip(_("The bytes number jumped on meeting an error"));
    Cancel = new wxButton(Panel1, ID_CANCEL, _("Cancel"), wxPoint(280,80), wxSize(64,24), 0, wxDefaultValidator, _T("ID_CANCEL"));
    Cancel->SetToolTip(_("Abort the copying "));
    Cancel->Disable();
    TextCtrlSrc = new wxTextCtrl(Panel1, ID_TEXTCTRLSRC, wxEmptyString, wxPoint(120,8), wxSize(224,23), 0, wxDefaultValidator, _T("ID_TEXTCTRLSRC"));
    TextCtrlSrc->SetMaxLength(255);
    ChoiceSrc = new wxButton(Panel1, ID_CHOICESRC, _("Choose"), wxPoint(360,8), wxSize(64,24), 0, wxDefaultValidator, _T("ID_CHOICESRC"));
    ChoiceSrc->SetToolTip(_("Choose the source file for copy"));
    TextCtrlDest = new wxTextCtrl(Panel1, ID_TEXTCTRLDEST, wxEmptyString, wxPoint(120,40), wxSize(224,23), 0, wxDefaultValidator, _T("ID_TEXTCTRLDEST"));
    TextCtrlDest->SetMaxLength(255);
    ChoiceDest = new wxButton(Panel1, ID_CHOICEDEST, _("Choose"), wxPoint(360,40), wxSize(64,24), 0, wxDefaultValidator, _T("ID_CHOICEDEST"));
    ChoiceDest->SetToolTip(_("Choose the destination file to copy"));
    About = new wxButton(Panel1, ID_ABOUT, _("About"), wxPoint(360,80), wxSize(64,24), 0, wxDefaultValidator, _T("ID_ABOUT"));
    BoxSizer1->Add(Panel1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    SetSizer(BoxSizer1);
    BoxSizer1->SetSizeHints(this);
    //Handle method association.
    Connect(ID_ABOUT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler
        (qcopyDialog::OnAbout));
    Connect(ID_CHOICESRC, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler
        (qcopyDialog::OnChoiceSrc));
    Connect(ID_CHOICEDEST, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler
        (qcopyDialog::OnChoiceDest));
    Connect(ID_COPY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler
        (qcopyDialog::OnCopy));
    Connect(ID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler
        (qcopyDialog::OnCancel));
    Connect(wxID_ANY, myEVT_GAUGE_FILLING_CHANGE, myGaugeEventHandler
        (qcopyDialog::OnGaugeFilling));
    //*)
}

qcopyDialog::~qcopyDialog()
{
    //(*Destroy(qcopyDialog)
    //(*destroy(UserVariables)
    if(srcFileName) delete[] srcFileName;
    if(destFileName) delete[] destFileName;
    //(*destroy(UserObjects)
    delete semaphore1;
    //*)
}

void qcopyDialog::OnQuit(wxCommandEvent& event)
{
    Close();
}

void qcopyDialog::OnAbout(wxCommandEvent& event)
{
    wxString msg = wxbuildinfo(long_f);
    msg = _("Program for recovery media files from scraped CD\n\
By Alexandru Olaru <Qumbetlian> 2007.\nLicense GNU GPL");
    wxMessageBox(msg, _("About Qcopy"), wxICON_INFORMATION, this);
}

void qcopyDialog::OnChoiceSrc(wxCommandEvent& event)
{
    wxFileDialog *fileDlg = new wxFileDialog(this, _("Choose the file for copy"),
        "", "", "all files (*)|*|files with extension (*.*)|*.*", wxFD_OPEN);
    if(fileDlg->ShowModal() == wxID_CANCEL){
        delete fileDlg;
        return;
    }
    wxString FileName = fileDlg->GetPath();
    delete fileDlg;
    if(!FileName.empty()) TextCtrlSrc->SetValue(FileName);
}

void qcopyDialog::OnChoiceDest(wxCommandEvent& event)
{
    wxFileDialog *fileDlg = new wxFileDialog(this, _("Choose the file to copy"),
        "", "", "all files (*)|*|files with extension (*.*)|*.*", wxFD_SAVE);
    if(fileDlg->ShowModal() == wxID_CANCEL){
        delete fileDlg;
        return;
    }
    wxString FileName = fileDlg->GetPath();
    delete fileDlg;
    if(!FileName.empty()) TextCtrlDest->SetValue(FileName);
}

void qcopyDialog::OnCopy(wxCommandEvent& event)
{
    bool continuation = false;
    int fileHandle;
    DIR *pdir = NULL;
    if(TextCtrlSrc->GetValue().IsNull()){
        wxMessageBox(_("Te source file field is empty\nPlease choose a source file!"), _("Warning!"), wxOK|wxICON_INFORMATION, this);
        return;
    }
    if(srcFileName) delete[] srcFileName;
    srcFileName = new char[(TextCtrlSrc->GetValue().Len() + 1) * sizeof(char)];
    strcpy(srcFileName, TextCtrlSrc->GetValue().c_str());
    if(pdir = opendir(srcFileName))
    {
        closedir(pdir);
        pdir = NULL;
        wxMessageBox(wxString::Format(_("\'%s\' is a directory.\nPlease choose a file!"), _(srcFileName)), _("Warning!"), wxOK|wxICON_INFORMATION, this);
        return;
    }
    fileHandle = open(srcFileName, O_RDONLY);
	if(fileHandle == -1){
	    wxMessageBox(wxString::Format("%s on opening \'%s\'", strerror(errno), srcFileName), _("Error"), wxOK|wxICON_ERROR, this);
	    return;
	}
	else close(fileHandle);
    if(TextCtrlDest->GetValue().IsNull()){
        wxMessageBox(_("Te destination file field is empty\nPlease choose a destination file!"), _("Warning!"), wxOK|wxICON_INFORMATION, this);
        return;
    }
    if(destFileName) delete[] destFileName;
    destFileName = new char[(TextCtrlDest->GetValue().Len() + 1) * sizeof(char)];
    strcpy(destFileName, TextCtrlDest->GetValue().c_str());
    if(pdir = opendir(destFileName))
    {
        closedir(pdir);
        pdir = NULL;
        wxMessageBox(wxString::Format(_("\'%s\' is a directory.\nPlease choose a file!"), _(destFileName)), _("Warning!"), wxOK|wxICON_INFORMATION, this);
        return;
    }
    if(access(destFileName, F_OK) != -1)
    {
        WFExistDialog wfeDlg(this, destFileName);
        if(wfeDlg.ShowModal() == CONTINUECOPY) continuation = true;
    }
    Copy->Disable();
    semaphore1->Post();
    copyThread *copy = new copyThread(this, srcFileName, destFileName, SpinCtrl->GetValue(), continuation, semaphore1);
    copy->Run();
    Cancel->Enable();
}

void qcopyDialog::OnCancel(wxCommandEvent& event)
{
    Cancel->Disable();
    semaphore1->Post();
    Copy->Enable();
}

void qcopyDialog::OnGaugeFilling(gaugeFillingEvent& event)
{
    switch(event.getStatus())
    {
        case RUNNING:
            Gauge1->SetValue(event.getFillingDegree());
            break;
        case FINISHED:
            Gauge1->SetValue(100);
            wxMessageBox(wxString::Format(_("The entire copying has ben finished"), _(destFileName)), _("OK"), wxOK|wxICON_INFORMATION, this);
        case STOPPED:
            Cancel->Disable();
            Copy->Enable();
    }
}
