/*
 Copyright (C) 2010-2017 Kristian Duske

 This file is part of TrenchBroom.

 TrenchBroom 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 3 of the License, or
 (at your option) any later version.

 TrenchBroom is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with TrenchBroom.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "KeyboardPreferencePane.h"

#include "Macros.h"
#include "Preferences.h"
#include "Assets/EntityDefinitionManager.h"
#include "Model/Tag.h"
#include "View/ActionManager.h"
#include "View/BorderLine.h"
#include "View/KeyboardShortcutGridTable.h"
#include "View/MapDocument.h"
#include "View/ViewConstants.h"

#include <wx/msgdlg.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/stattext.h>

namespace TrenchBroom {
    namespace View {
        KeyboardPreferencePane::KeyboardPreferencePane(wxWindow* parent, MapDocument* document) :
        PreferencePane(parent),
        m_grid(nullptr),
        m_table(nullptr) {
            wxWindow* menuShortcutGrid = createMenuShortcutGrid(document);

            wxSizer* outerSizer = new wxBoxSizer(wxVERTICAL);
            outerSizer->Add(menuShortcutGrid, 1, wxEXPAND);
            outerSizer->SetItemMinSize(menuShortcutGrid, 900, 550);
            SetSizerAndFit(outerSizer);
        }

        void KeyboardPreferencePane::OnGridSize(wxSizeEvent& event) {
            if (IsBeingDeleted()) return;

            int width = m_grid->GetClientSize().x;
            m_grid->AutoSizeColumn(0);
            m_grid->AutoSizeColumn(1);
            int colSize = width - m_grid->GetColSize(0) - m_grid->GetColSize(1);
            if (colSize < -1 || colSize == 0)
                colSize = -1;
            m_grid->SetColSize(2, colSize);
            event.Skip();
        }

        wxWindow* KeyboardPreferencePane::createMenuShortcutGrid(MapDocument* document) {
            ActionManager::ShortcutEntryList entries;
            ActionManager& actionManager = ActionManager::instance();
            if (document != nullptr) {
                const auto& definitions = document->entityDefinitionManager().definitions();
                actionManager.getShortcutEntries(document->smartTags(), definitions, entries);
            } else {
                actionManager.getShortcutEntries(std::list<Model::SmartTag>{}, Assets::EntityDefinitionList{}, entries);
            }

            wxPanel* container = new wxPanel(this);

            m_table = new KeyboardShortcutGridTable(std::move(entries));
            m_grid = new wxGrid(container, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
            m_grid->Bind(wxEVT_SIZE, &KeyboardPreferencePane::OnGridSize, this);

            m_grid->SetTable(m_table, true, wxGrid::wxGridSelectRows);
            m_grid->SetColLabelSize(18);
            m_grid->SetDefaultCellBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX));
            m_grid->HideRowLabels();
            m_grid->SetCellHighlightPenWidth(0);
            m_grid->SetCellHighlightROPenWidth(0);

            m_grid->DisableColResize(0);
            m_grid->DisableColResize(1);
            m_grid->DisableColResize(2);
            m_grid->DisableDragColMove();
            m_grid->DisableDragCell();
            m_grid->DisableDragColSize();
            m_grid->DisableDragGridSize();
            m_grid->DisableDragRowSize();

            wxStaticText* infoText = new wxStaticText(container, wxID_ANY, "Click twice on a key combination to edit the shortcut. Press delete or backspace to delete a shortcut.");
#if defined __APPLE__
            infoText->SetFont(*wxSMALL_FONT);
#endif

            wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
            sizer->Add(m_grid, 1, wxEXPAND);
            sizer->Add(new BorderLine(container, BorderLine::Direction_Horizontal), 0, wxEXPAND);
            sizer->AddSpacer(LayoutConstants::WideVMargin);
            sizer->Add(infoText, 0, wxALIGN_CENTER);
            sizer->AddSpacer(LayoutConstants::NarrowVMargin);
            container->SetSizer(sizer);

            return container;
        }

        bool KeyboardPreferencePane::doCanResetToDefaults() {
            return true;
        }

        void KeyboardPreferencePane::doResetToDefaults() {
            ActionManager& actionManager = ActionManager::instance();
            actionManager.resetShortcutsToDefaults();
        }

        void KeyboardPreferencePane::doUpdateControls() {
            m_table->update();
        }

        bool KeyboardPreferencePane::doValidate() {
            m_grid->SaveEditControlValue();
            if (m_table->hasDuplicates()) {
                wxMessageBox("Please fix all conflicting shortcuts (highlighted in red).", "Error", wxOK | wxCENTRE, this);
                return false;
            }
            return true;
        }
    }
}
