#include "avChangesDlg.h"

//(*InternalHeaders(avChangesDlg)
#include <wx/intl.h>
#include <wx/string.h>
//*)

#include <wx/arrstr.h>
#include <wx/msgdlg.h>
#include <wx/ffile.h>
#include <wx/filefn.h>

//Choices to initialize the l_TypesArray
const wxString strTypes[] =
{
    _T("Added"), _T("Applied"), _T("Cleaned"),
    _T("Fixed"), _T("New"), _T("Removed"),
    _T("Typo"), _T("Updated")
};

//List of choices available for the data grid column [Type]
const wxArrayString g_TypesArray(sizeof(strTypes) / sizeof(wxString), strTypes);

//(*IdInit(avChangesDlg)
const wxWindowID avChangesDlg::ID_ADD_BUTTON = wxNewId();
const wxWindowID avChangesDlg::ID_EDIT_BUTTON = wxNewId();
const wxWindowID avChangesDlg::ID_DELETE_BUTTON = wxNewId();
const wxWindowID avChangesDlg::ID_CHANGES_GRID = wxNewId();
const wxWindowID avChangesDlg::ID_SAVE_BUTTON = wxNewId();
const wxWindowID avChangesDlg::ID_WRITE_BUTTON = wxNewId();
const wxWindowID avChangesDlg::ID_CANCEL_BUTTON = wxNewId();
//*)

BEGIN_EVENT_TABLE(avChangesDlg,wxScrollingDialog)
    //(*EventTable(avChangesDlg)
    //*)
END_EVENT_TABLE()

avChangesDlg::avChangesDlg(wxWindow* parent,wxWindowID /*id*/)
{
    //(*Initialize(avChangesDlg)
    wxBoxSizer* sizerButtons;
    wxBoxSizer* sizerConfirmation;

    Create(parent, wxID_ANY, _("AutoVersioning :: Changes Log"), wxDefaultPosition, wxDefaultSize, wxCAPTION|wxRESIZE_BORDER, _T("wxID_ANY"));
    BoxSizer1 = new wxBoxSizer(wxVERTICAL);
    sizerButtons = new wxBoxSizer(wxHORIZONTAL);
    btnAdd = new wxButton(this, ID_ADD_BUTTON, _("Add"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_ADD_BUTTON"));
    btnAdd->SetToolTip(_("Adds another row to the data grid"));
    sizerButtons->Add(btnAdd, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    btnEdit = new wxButton(this, ID_EDIT_BUTTON, _("Edit"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_EDIT_BUTTON"));
    btnEdit->SetToolTip(_("Enters edit mode"));
    sizerButtons->Add(btnEdit, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    btnDelete = new wxButton(this, ID_DELETE_BUTTON, _("Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_DELETE_BUTTON"));
    btnDelete->SetToolTip(_("Deletes the selected row"));
    sizerButtons->Add(btnDelete, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(sizerButtons, 0, wxALL|wxEXPAND, 5);
    grdChanges = new wxGrid(this, ID_CHANGES_GRID, wxDefaultPosition, wxDefaultSize, 0, _T("ID_CHANGES_GRID"));
    BoxSizer1->Add(grdChanges, 1, wxALL|wxEXPAND, 5);
    sizerConfirmation = new wxBoxSizer(wxHORIZONTAL);
    btnSave = new wxButton(this, ID_SAVE_BUTTON, _("Save"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_SAVE_BUTTON"));
    btnSave->SetDefault();
    btnSave->SetToolTip(_("Save the changes for later use"));
    sizerConfirmation->Add(btnSave, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    btnWrite = new wxButton(this, ID_WRITE_BUTTON, _("Write"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_WRITE_BUTTON"));
    btnWrite->SetToolTip(_("Write the changes to the changeslog and clean the data grid"));
    sizerConfirmation->Add(btnWrite, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    btnCancel = new wxButton(this, ID_CANCEL_BUTTON, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CANCEL_BUTTON"));
    btnCancel->SetToolTip(_("Discards any change made"));
    sizerConfirmation->Add(btnCancel, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(sizerConfirmation, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5);
    SetSizer(BoxSizer1);
    BoxSizer1->SetSizeHints(this);
    Center();

    Connect(ID_ADD_BUTTON,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(avChangesDlg::OnBtnAddClick));
    Connect(ID_EDIT_BUTTON,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(avChangesDlg::OnBtnEditClick));
    Connect(ID_DELETE_BUTTON,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(avChangesDlg::OnBtnDeleteClick));
    Connect(ID_SAVE_BUTTON,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(avChangesDlg::OnBtnSaveClick));
    Connect(ID_WRITE_BUTTON,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(avChangesDlg::OnBtnWriteClick));
    Connect(ID_CANCEL_BUTTON,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(avChangesDlg::OnBtnCancelClick));
    //*)

    grdChanges->CreateGrid(0, 2);
    grdChanges->SetColLabelValue(0, _("Type"));
    grdChanges->SetColLabelValue(1, _("Description"));

    grdChanges->AutoSize();
    grdChanges->SetColSize(0, 60);
    grdChanges->SetColSize(1, 645);

    btnEdit->Enable(false);
    btnDelete->Enable(false);
}

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

//{Event Functions
void avChangesDlg::OnBtnAddClick(wxCommandEvent& /*event*/)
{
    grdChanges->AppendRows(1);
    grdChanges->SetCellEditor(grdChanges->GetNumberRows()-1, 0, new wxGridCellChoiceEditor(g_TypesArray,true));
    grdChanges->SetGridCursor(grdChanges->GetNumberRows()-1, 0);
    grdChanges->EnableCellEditControl(true);
    btnEdit->Enable(true);
    btnDelete->Enable(true);
}

void avChangesDlg::OnBtnEditClick(wxCommandEvent& /*event*/)
{
    if (grdChanges->CanEnableCellControl())
        grdChanges->EnableCellEditControl(true);
    else
        wxBell();
}

void avChangesDlg::OnBtnDeleteClick(wxCommandEvent& /*event*/)
{
    const int row = grdChanges->GetGridCursorRow();
    if (row != -1)
    {
        grdChanges->SelectRow(row);
        if (wxMessageBox(_("You are about to delete the selected row"), _("Warning"), wxICON_EXCLAMATION|wxOK|wxCANCEL, this) == wxOK)
        {
            grdChanges->DeleteRows(row, 1, true);
            if (grdChanges->GetNumberRows() == 0)
            {
                btnEdit->Enable(false);
                btnDelete->Enable(false);
            }
        }
    }
    else
        wxBell();
}

void avChangesDlg::OnBtnSaveClick(wxCommandEvent& /*event*/)
{
    const int rows = grdChanges->GetNumberRows();
    if (rows != 0)
    {
        wxFFile saveTempChangesFile;
        saveTempChangesFile.Open(m_tempChangesFile, "w");

        wxString tempChanges;

        for (int row = 0; row < rows; ++row)
        {
            tempChanges += grdChanges->GetCellValue(row, 0);
            tempChanges += '\t';

            tempChanges += grdChanges->GetCellValue(row, 1);
            tempChanges += '\n';
        }

        saveTempChangesFile.Write(tempChanges);
        EndModal(0);
    }
    else
    {
        wxMessageBox(_("There are no rows in the data grid to write."), _("Error"), wxICON_ERROR);
    }
}

void avChangesDlg::OnBtnWriteClick(wxCommandEvent& /*event*/)
{
    const int rows = grdChanges->GetNumberRows();
    if (rows != 0)
    {
        for (int row = 0; row < rows; ++row)
        {
            if (!grdChanges->GetCellValue(row, 0).empty())
            {
                m_changes += grdChanges->GetCellValue(row, 0) + ": ";
            }

            m_changes += grdChanges->GetCellValue(row, 1);

            if (row != rows-1)
            {
                m_changes += '\n';
            }
        }

        wxRemoveFile(m_tempChangesFile);
        EndModal(0);
    }
    else
    {
        wxMessageBox(_("There are no rows in the data grid to write."), _("Error"), wxICON_ERROR);
    }
}

void avChangesDlg::OnBtnCancelClick(wxCommandEvent& /*event*/)
{
    EndModal(0);
}
//}

//{Const Properties
void avChangesDlg::SetTemporaryChangesFile(const wxString& fileName)
{
    m_tempChangesFile = fileName;

    wxFFile tempChangesFile;
    if (tempChangesFile.Open(m_tempChangesFile))
    {
        wxString fileContent, type, description;

        tempChangesFile.ReadAll(&fileContent);

        bool isType = true;
        grdChanges->BeginBatch();

        for (size_t i = 0; i < fileContent.Len(); ++i)
        {
            if (isType)
            {
                if (fileContent[i] != L'\t')
                {
                    type += fileContent[i];
                }
                else
                {
                    isType = false;
                }
            }
            else
            {
                if (fileContent[i] != L'\n')
                {
                    description += fileContent[i];
                }
                else
                {
                    grdChanges->AppendRows(1);
                    grdChanges->SetCellValue(grdChanges->GetNumberRows()-1, 0, type);
                    grdChanges->SetCellEditor(grdChanges->GetNumberRows()-1, 0, new wxGridCellChoiceEditor(g_TypesArray,true));
                    grdChanges->SetCellValue(grdChanges->GetNumberRows()-1, 1, description);
                    type = _T("");
                    description = _T("");
                    isType = true;
                }
            }
        }

        grdChanges->AutoSize();
        grdChanges->EndBatch();
        btnEdit->Enable(grdChanges->GetNumberRows() != 0);
        btnDelete->Enable(grdChanges->GetNumberRows() != 0);
    }
}

const wxString& avChangesDlg::Changes() const
{
    return m_changes;
}
//}
