//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright            : (C) 2014 Eran Ifrah
// file name            : ps_debugger_page.cpp
//
// -------------------------------------------------------------------------
// A
//              _____           _      _     _ _
//             /  __ \         | |    | |   (_) |
//             | /  \/ ___   __| | ___| |    _| |_ ___
//             | |    / _ \ / _  |/ _ \ |   | | __/ _ )
//             | \__/\ (_) | (_| |  __/ |___| | ||  __/
//              \____/\___/ \__,_|\___\_____/_|\__\___|
//
//                                                  F i l e
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

#include "ps_debugger_page.h"
#include <wx/filename.h>
#include <wx/filedlg.h>
#include <wx/dirdlg.h>
#include <project.h>
#include <workspace.h>
#include <wx/filedlg.h>
#include "globals.h"

PSDebuggerPage::PSDebuggerPage( wxWindow* parent, ProjectSettingsDlg* dlg )
    : PSDebuggerPageBase( parent )
    , m_dlg(dlg)
{
}

void PSDebuggerPage::OnCmdEvtVModified( wxCommandEvent& event )
{
    wxUnusedVar(event);
    m_dlg->SetIsDirty(true);
}

void PSDebuggerPage::OnStcEvtVModified( wxStyledTextEvent& event )
{
    event.Skip();
    m_dlg->SetIsDirty(true);
}

void PSDebuggerPage::OnRemoteDebugUI( wxUpdateUIEvent& event )
{
    event.Enable(m_checkBoxDbgRemote->IsChecked());
}

void PSDebuggerPage::Load(BuildConfigPtr buildConf)
{
    Clear();
    m_textCtrlDbgCmds->ChangeValue(buildConf->GetDebuggerStartupCmds());
    m_textCtrlDbgPostConnectCmds->ChangeValue(buildConf->GetDebuggerPostRemoteConnectCmds());
    m_checkBoxDbgRemote->SetValue(buildConf->GetIsDbgRemoteTarget());
    m_textCtrl1DbgHost->ChangeValue(buildConf->GetDbgHostName());
    m_textCtrlDbgPort->ChangeValue(buildConf->GetDbgHostPort());
    m_textCtrlDebuggerPath->ChangeValue(buildConf->GetDebuggerPath());
    m_checkBoxDbgRemoteExt->SetValue(buildConf->GetIsDbgRemoteExtended());

    const wxArrayString &searchPaths = buildConf->GetDebuggerSearchPaths();
    for(size_t i=0; i<searchPaths.GetCount(); ++i) {
        wxVector<wxVariant> cols;
        cols.push_back( searchPaths.Item(i) );
        m_dvListCtrlDebuggerSearchPaths->AppendItem( cols , (wxUIntPtr)NULL );
    }
}

void PSDebuggerPage::Save(BuildConfigPtr buildConf, ProjectSettingsPtr projSettingsPtr)
{
    buildConf->SetDebuggerStartupCmds(m_textCtrlDbgCmds->GetValue());
    buildConf->SetDebuggerPostRemoteConnectCmds(m_textCtrlDbgPostConnectCmds->GetValue());
    buildConf->SetIsDbgRemoteTarget(m_checkBoxDbgRemote->IsChecked());
    buildConf->SetDbgHostName(m_textCtrl1DbgHost->GetValue());
    buildConf->SetDbgHostPort(m_textCtrlDbgPort->GetValue());
    buildConf->SetDebuggerPath(m_textCtrlDebuggerPath->GetValue());
    buildConf->SetIsDbgRemoteExtended(m_checkBoxDbgRemoteExt->IsChecked());

    wxArrayString searchPaths;
    int nCount = m_dvListCtrlDebuggerSearchPaths->GetItemCount();
    for(int i=0; i<nCount; ++i) {
        wxVariant colValue;
        m_dvListCtrlDebuggerSearchPaths->GetValue(colValue, i, 0);
        if ( !colValue.IsNull() ) {
            searchPaths.Add( colValue.GetString() );
        }
    }
    buildConf->SetDebuggerSearchPaths(searchPaths);
}

void PSDebuggerPage::Clear()
{
    m_textCtrlDebuggerPath->Clear();
    m_textCtrl1DbgHost->Clear();
    m_textCtrlDbgCmds->Clear();
    m_textCtrlDbgPort->Clear();
    m_textCtrlDbgPostConnectCmds->Clear();
    m_dvListCtrlDebuggerSearchPaths->DeleteAllItems();
    m_checkBoxDbgRemote->SetValue(false);
}

void PSDebuggerPage::OnBrowseForDebuggerPath(wxCommandEvent& event)
{
    wxString debugger_path = ::wxFileSelector(_("Select debugger:"));

    if ( !debugger_path.IsEmpty() ) {
        wxString errMsg;
        ProjectPtr proj = clCxxWorkspaceST::Get()->FindProjectByName(m_dlg->GetProjectName(), errMsg);
        if ( proj ) {
            wxFileName fnDebuggerPath( debugger_path );
            wxString project_path = proj->GetFileName().GetPath();
            if ( fnDebuggerPath.MakeRelativeTo( project_path ) ) {
                debugger_path = fnDebuggerPath.GetFullPath();
            }
        }
        m_textCtrlDebuggerPath->ChangeValue( debugger_path );
        m_dlg->SetIsDirty(true);
    }
}
void PSDebuggerPage::OnAddDebuggerSearchPath(wxCommandEvent& event)
{
    wxString path = ::wxDirSelector();
    if ( !path.IsEmpty() ) {
        wxVector<wxVariant> cols;
        cols.push_back( path );
        m_dvListCtrlDebuggerSearchPaths->AppendItem(cols, (wxUIntPtr)NULL);
        m_dlg->SetIsDirty(true);
    }
}

void PSDebuggerPage::OnDeleteDebuggerSearchPath(wxCommandEvent& event)
{
    wxDataViewItemArray items;
    m_dvListCtrlDebuggerSearchPaths->GetSelections( items );
    if ( items.IsEmpty() )
        return;

    for(size_t i=0; i<items.GetCount(); ++i) {
        m_dvListCtrlDebuggerSearchPaths->DeleteItem( m_dvListCtrlDebuggerSearchPaths->ItemToRow( items.Item(i) ) );
    }
    m_dlg->SetIsDirty(true);
}

void PSDebuggerPage::OnDeleteDebuggerSearchPathUI(wxUpdateUIEvent& event)
{
    event.Enable( m_dvListCtrlDebuggerSearchPaths->GetSelectedItemsCount() );
}

void PSDebuggerPage::OnItemActivated(wxDataViewEvent& event)
{
    wxVariant value;
    m_dvListCtrlDebuggerSearchPaths->GetValue(value, m_dvListCtrlDebuggerSearchPaths->ItemToRow(event.GetItem()), 0);

    if ( !value.IsNull() ) {

        wxString path = value.GetString();
        path = ::wxDirSelector(_("Select a folder"), path);

        if ( !path.IsEmpty() ) {
            m_dvListCtrlDebuggerSearchPaths->DeleteItem( m_dvListCtrlDebuggerSearchPaths->ItemToRow(event.GetItem()) );
            ::PostCall(this, (clEventFunc_t) &PSDebuggerPage::DoAddPath, new wxStringClientData(path));

        }
    }
}

void PSDebuggerPage::DoAddPath(wxStringClientData* path)
{
    wxVector<wxVariant> cols;
    cols.push_back( path->GetData() );
    m_dvListCtrlDebuggerSearchPaths->AppendItem(cols, (wxUIntPtr)NULL);
    m_dlg->SetIsDirty(true);
}

void PSDebuggerPage::OnProjectEnabledUI(wxUpdateUIEvent& event)
{
    event.Enable( m_dlg->IsProjectEnabled() );
}
