/**************************************************************************
 *   Copyright (C) 2013 by David S. Register                               *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program 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 this program; if not, see <https://www.gnu.org/licenses/>. *
 ***************************************************************************/

/**
 * \file
 *
 * Implement go_to_position_dlg.h -- Go to position dialog...
 */

#include <wx/button.h>
#include <wx/clipbrd.h>
#include <wx/dialog.h>
#include <wx/event.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/string.h>
#include <wx/textctrl.h>
#include <wx/wxprec.h>

#include "go_to_position_dlg.h"

#include "model/position_parser.h"
#include "chcanv.h"
#include "mark_info.h"
#include "navutil.h"
#include "top_frame.h"

GoToPositionDialog* pGoToPositionDialog;

/*!
 * GoToPositionDialog type definition
 */

/*!
 * GoToPositionDialog event table definition
 */
BEGIN_EVENT_TABLE(GoToPositionDialog, wxDialog)

////@begin GoToPositionDialog event table entries

EVT_BUTTON(ID_GOTOPOS_CANCEL, GoToPositionDialog::OnGoToPosCancelClick)
EVT_BUTTON(ID_GOTOPOS_OK, GoToPositionDialog::OnGoToPosOkClick)
EVT_COMMAND(ID_LATCTRL, EVT_LLCHANGE, GoToPositionDialog::OnPositionCtlUpdated)
EVT_COMMAND(ID_LONCTRL, EVT_LLCHANGE, GoToPositionDialog::OnPositionCtlUpdated)

////@end GoToPositionDialog event table entries

END_EVENT_TABLE()

/*!
 * GoToPositionDialog constructors
 */

GoToPositionDialog::GoToPositionDialog() {}

GoToPositionDialog::GoToPositionDialog(wxWindow* parent, wxWindowID id,
                                       const wxString& caption,
                                       const wxPoint& pos, const wxSize& size,
                                       long style) {
  long wstyle =
      wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT;

  Create(parent, id, caption, pos, size, wstyle);
}

GoToPositionDialog::~GoToPositionDialog() {
  delete m_MarkLatCtl;
  delete m_MarkLonCtl;
}

/*!
 * GoToPositionDialog creator
 */

bool GoToPositionDialog::Create(wxWindow* parent, wxWindowID id,
                                const wxString& caption, const wxPoint& pos,
                                const wxSize& size, long style) {
  SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
  wxDialog::Create(parent, id, caption, pos, size, style);

  m_hostCanvas = NULL;

  CreateControls();
  GetSizer()->SetSizeHints(this);
  Centre();

  return TRUE;
}

/*!
 * Control creation for GoToPositionDialog
 */

void GoToPositionDialog::CreateControls() {
  GoToPositionDialog* itemDialog1 = this;

  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
  itemDialog1->SetSizer(itemBoxSizer2);

  wxStaticBox* itemStaticBoxSizer4Static =
      new wxStaticBox(itemDialog1, wxID_ANY, _("Position"));

  wxStaticBoxSizer* itemStaticBoxSizer4 =
      new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxVERTICAL);
  itemBoxSizer2->Add(itemStaticBoxSizer4, 0, wxEXPAND | wxALL, 5);

  wxStaticText* itemStaticText5 =
      new wxStaticText(itemDialog1, wxID_STATIC, _("Latitude"),
                       wxDefaultPosition, wxDefaultSize, 0);
  itemStaticBoxSizer4->Add(itemStaticText5, 0,
                           wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);

  m_MarkLatCtl = new wxTextCtrl(itemDialog1, ID_LATCTRL, "", wxDefaultPosition,
                                wxSize(180, -1), 0);
  itemStaticBoxSizer4->Add(
      m_MarkLatCtl, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,
      5);

  wxStaticText* itemStaticText6 =
      new wxStaticText(itemDialog1, wxID_STATIC, _("Longitude"),
                       wxDefaultPosition, wxDefaultSize, 0);
  itemStaticBoxSizer4->Add(itemStaticText6, 0,
                           wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);

  m_MarkLonCtl = new wxTextCtrl(itemDialog1, ID_LONCTRL, "", wxDefaultPosition,
                                wxSize(180, -1), 0);
  itemStaticBoxSizer4->Add(
      m_MarkLonCtl, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,
      5);

  wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
  itemBoxSizer2->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);

  m_CancelButton = new wxButton(itemDialog1, ID_GOTOPOS_CANCEL, _("Cancel"),
                                wxDefaultPosition, wxDefaultSize, 0);
  itemBoxSizer16->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);

  m_OKButton = new wxButton(itemDialog1, ID_GOTOPOS_OK, _("OK"),
                            wxDefaultPosition, wxDefaultSize, 0);
  itemBoxSizer16->Add(m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
  m_OKButton->SetDefault();

  SetColorScheme((ColorScheme)0);
}

void GoToPositionDialog::SetColorScheme(ColorScheme cs) { DimeControl(this); }

bool GoToPositionDialog::ShowToolTips() { return TRUE; }

void GoToPositionDialog::OnGoToPosCancelClick(wxCommandEvent& event) {
  Hide();
  if (m_hostCanvas) m_hostCanvas->ReloadVP();

  event.Skip();
}

void GoToPositionDialog::OnGoToPosOkClick(wxCommandEvent& event) {
  double lat, lon;

  if (m_MarkLatCtl->GetValue().Length() == 0) goto noGo;
  if (m_MarkLonCtl->GetValue().Length() == 0) goto noGo;

  lat = fromDMM(m_MarkLatCtl->GetValue());
  lon = fromDMM(m_MarkLonCtl->GetValue());

  if (lat == 0.0 && lon == 0.0) goto noGo;
  if (lat > 80.0 || lat < -80.0) goto noGo;
  if (lon > 180.0 || lon < -180.0) goto noGo;

  if (m_hostCanvas) {
    top_frame::Get()->JumpToPosition(m_hostCanvas, lat, lon,
                                     m_hostCanvas->GetVPScale());
  }
  Hide();
  event.Skip();
  return;

noGo:
  wxBell();
  event.Skip();
  return;
}

void GoToPositionDialog::CheckPasteBufferForPosition() {
  if (wxTheClipboard->Open()) {
    wxTextDataObject data;
    wxTheClipboard->GetData(data);
    wxString pasteBuf = data.GetText();

    PositionParser pparse(pasteBuf);

    if (pparse.IsOk()) {
      m_MarkLatCtl->SetValue(pparse.GetLatitudeString());
      m_MarkLonCtl->SetValue(pparse.GetLongitudeString());
    }
    wxTheClipboard->Close();
  }
}

void GoToPositionDialog::OnPositionCtlUpdated(wxCommandEvent& event) {
  // We do not want to change the position on lat/lon now
}
