//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright            : (C) 2008 by Eran Ifrah
// file name            : depend_dlg_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 "manager.h"
#include "project.h"
#include "depend_dlg_page.h"

DependenciesPage::DependenciesPage(wxWindow* parent, const wxString& projectName)
    : DependenciesPageBase(parent)
    , m_projectName(projectName)
    , m_dirty(false)
{
    Init();
}

void DependenciesPage::OnConfigChanged(wxCommandEvent& event)
{
    if(m_dirty) {
        // save old configuration
        if(wxMessageBox(
               wxString::Format(_("Build order for configuration '%s' has been modified, would you like to save it?"),
                                m_currentSelection.GetData()),
               _("CodeLite"), wxYES_NO | wxICON_QUESTION) == wxYES) {
            Save();
        }
        m_dirty = false;
    }

    m_currentSelection = event.GetString();
    // switch to new configuration
    DoPopulateControl(m_currentSelection);
}

void DependenciesPage::OnMoveUp(wxCommandEvent& event)
{
    wxUnusedVar(event);
    OnUpCommand(m_listBoxBuildOrder);
}

void DependenciesPage::OnMoveDown(wxCommandEvent& event)
{
    wxUnusedVar(event);
    OnDownCommand(m_listBoxBuildOrder);
}

void DependenciesPage::OnUpCommand(wxListBox* list)
{
    wxString selectedString = list->GetStringSelection();

    int sel = list->GetSelection();
    if(sel == wxNOT_FOUND) {
        return;
    }

    sel--;
    if(sel < 0) {
        return;
    }

    // sel contains the new position we want to place the selection string
    list->Delete(sel + 1);
    list->Insert(selectedString, sel);
    list->Select(sel);
    m_dirty = true;
}

void DependenciesPage::OnDownCommand(wxListBox* list)
{
    int sel = list->GetSelection();
    if(sel == wxNOT_FOUND) {
        return;
    }

    sel++;
    if(sel >= (int)list->GetCount()) {
        return;
    }

    // sel contains the new position we want to place the selection string
    wxString oldStr = list->GetString(sel);

    list->Delete(sel);
    list->Insert(oldStr, sel - 1);
    list->Select(sel);
    m_dirty = true;
}

void DependenciesPage::Save()
{
    // Save only if its dirty...
    if(m_dirty) {
        ProjectPtr proj = ManagerST::Get()->GetProject(m_projectName);

        wxArrayString depsArr;
        for(size_t i = 0; i < m_listBoxBuildOrder->GetCount(); i++) {
            depsArr.Add(m_listBoxBuildOrder->GetString((unsigned int)i));
        }

        if(m_currentSelection.IsEmpty()) {
            return;
        }

        proj->SetDependencies(depsArr, m_currentSelection);
    }
    m_dirty = false;
}

void DependenciesPage::OnCheckListItemToggled(wxCommandEvent& event)
{
    int item = event.GetSelection();
    wxString name = m_checkListProjectList->GetString((unsigned int)item);
    if(!m_checkListProjectList->IsChecked((unsigned int)item)) {
        unsigned int buildOrderId = m_listBoxBuildOrder->FindString(name);
        if(buildOrderId != (unsigned int)wxNOT_FOUND) {
            m_listBoxBuildOrder->Delete(buildOrderId);
        }
    } else {
        m_listBoxBuildOrder->Append(name);
    }
    m_dirty = true;
}

void DependenciesPage::Init()
{
    wxString errMsg;
    ProjectPtr proj = clCxxWorkspaceST::Get()->FindProjectByName(m_projectName, errMsg);
    if(proj) {

        // populate the choice control with the list of available configurations for this project
        ProjectSettingsPtr settings = proj->GetSettings();
        if(settings) {
            ProjectSettingsCookie cookie;
            BuildConfigPtr bldConf = settings->GetFirstBuildConfiguration(cookie);
            while(bldConf) {
                m_choiceProjectConfig->Append(bldConf->GetName());
                bldConf = settings->GetNextBuildConfiguration(cookie);
            }
        }

        // by default select the first configuration
        if(m_choiceProjectConfig->GetCount() > 0) {
            m_choiceProjectConfig->SetSelection(0);
        }

        // select the active configuration
        BuildConfigPtr selBuildConf = clCxxWorkspaceST::Get()->GetProjBuildConf(m_projectName, wxEmptyString);
        if(selBuildConf) {
            int where = m_choiceProjectConfig->FindString(selBuildConf->GetName());
            if(where != wxNOT_FOUND) {
                m_choiceProjectConfig->SetSelection(where);
            }
        }

        m_currentSelection = m_choiceProjectConfig->GetStringSelection();
        DoPopulateControl(m_choiceProjectConfig->GetStringSelection());

    } else {
        wxMessageBox(errMsg, _("CodeLite"));
        return;
    }
}

void DependenciesPage::DoPopulateControl(const wxString& configuration)
{
    wxString errMsg;
    ProjectPtr proj = clCxxWorkspaceST::Get()->FindProjectByName(m_projectName, errMsg);
    if(!proj) {
        return;
    }

    m_listBoxBuildOrder->Clear();
    m_checkListProjectList->Clear();

    // initialize the build order listbox
    wxArrayString depArr = proj->GetDependencies(configuration);
    size_t i = 0;
    for(i = 0; i < depArr.GetCount(); i++) {
        wxString item = depArr.Item(i);
        m_listBoxBuildOrder->Append(item);
    }

    // initialize the project dependencies check list
    wxArrayString projArr;
    ManagerST::Get()->GetProjectList(projArr);

    for(i = 0; i < projArr.GetCount(); i++) {

        if(projArr.Item(i) != m_projectName) {
            int idx = m_checkListProjectList->Append(projArr.Item(i));
            m_checkListProjectList->Check(idx, depArr.Index(projArr.Item(i)) != wxNOT_FOUND);
        }
    }
}

void DependenciesPage::OnApplyButton(wxCommandEvent& event)
{
    wxUnusedVar(event);
    Save();
}

void DependenciesPage::OnApplyButtonUI(wxUpdateUIEvent& event) { event.Enable(m_dirty); }
