#pragma once

// subtitleeditor -- a tool to create or edit subtitle
//
// https://kitone.github.io/subtitleeditor/
// https://github.com/kitone/subtitleeditor/
//
// Copyright @ 2005-2018, kitone
//
// 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 3 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 <http://www.gnu.org/licenses/>.

#include <debug.h>
#include <gtkmm.h>
#include "cellrenderercustom.h"

template <class T>
class CellRendererCustom : public Gtk::CellRendererText {
 public:
  CellRendererCustom();

  virtual Gtk::CellEditable* start_editing_vfunc(
      GdkEvent* event, Gtk::Widget& widget, const Glib::ustring& path,
      const Gdk::Rectangle& background_area, const Gdk::Rectangle& cell_area,
      Gtk::CellRendererState flags);

 protected:
  // Disable all actions.
  virtual void begin_editing();

  // Enable all actions.
  virtual void finish_editing();

  void cell_editing_done(const Glib::ustring& path);

 protected:
  T* m_editable;
};

template <class T>
CellRendererCustom<T>::CellRendererCustom()
    : Glib::ObjectBase(typeid(CellRendererCustom)),
      Gtk::CellRendererText(),
      m_editable(NULL) {
  se_dbg(SE_DBG_VIEW);
}

template <class T>
Gtk::CellEditable* CellRendererCustom<T>::start_editing_vfunc(
    GdkEvent* /*event*/, Gtk::Widget& /*widget*/, const Glib::ustring& path,
    const Gdk::Rectangle& /*background_area*/, const Gdk::Rectangle& cell_area,
    Gtk::CellRendererState /*flags*/) {
  se_dbg(SE_DBG_VIEW);

  if (!property_editable())
    return nullptr;

  m_editable = manage(new T);
  m_editable->set_size_request(cell_area.get_width(), cell_area.get_height());

  m_editable->signal_editing_done().connect(sigc::bind(
      sigc::mem_fun(*this, &CellRendererCustom<T>::cell_editing_done), path));

  // prepare widget
  if (Gtk::Entry* entry = dynamic_cast<Gtk::Entry*>(m_editable)) {
    entry->set_has_frame(false);
    entry->set_alignment(property_xalign());
  }
  m_editable->set_text(property_text());

  // Begin/Finish editing (Fix #10494)
  // Disable actions during editing. Enable at the exit.
  begin_editing();

  m_editable->signal_remove_widget().connect(
      sigc::mem_fun(*this, &CellRendererCustom<T>::finish_editing));

  m_editable->show();
  return m_editable;
}

// Disable all actions.
template <class T>
void CellRendererCustom<T>::begin_editing() {
  se_dbg(SE_DBG_VIEW);
}

// Enable all actions.
template <class T>
void CellRendererCustom<T>::finish_editing() {
  se_dbg(SE_DBG_VIEW);
}

template <class T>
void CellRendererCustom<T>::cell_editing_done(const Glib::ustring& path) {
  se_dbg(SE_DBG_VIEW);

  if (m_editable == NULL) {
    se_dbg_msg(SE_DBG_VIEW, "m_editable is NULL");
    return;
  }

  Glib::ustring text = m_editable->get_text();
  se_dbg_msg(SE_DBG_VIEW, "text from editable='%s'", text.c_str());

  // Define to NULL to avoid a duplicate call
  m_editable = NULL;
  edited(path, text);

  finish_editing();
}
