/***********************************************************************************

    Copyright (C) 2007-2020 Ahmet Öztürk (aoz_2@yahoo.com)

    This file is part of Lifeograph.

    Lifeograph 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.

    Lifeograph 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 Lifeograph.  If not, see <http://www.gnu.org/licenses/>.

***********************************************************************************/


#ifndef LIFEOGRAPH_UI_ENTRY_HEADER
#define LIFEOGRAPH_UI_ENTRY_HEADER


#include <thread>
#include <mutex>

#include "helpers.hpp"  // i18n headers
#include "diary.hpp"
#include "widgets/widget_textviewedit.hpp"


namespace LIFEO
{

class UIEntry
{
    public:
                                UIEntry();

        void                    handle_login();
        void                    handle_edit_enabled();
        void                    handle_logout();

        void                    show( Entry* );
        void                    show( const Match& );
        void                    refresh(); // updates text with changes made elsewhere
        bool                    is_cur_entry( const Entry* entry ) const
        { return( entry == m_p2entry ); }
        Entry*                  get_cur_entry() const
        { return m_p2entry; }
        void                    go_back();
        void                    go_forward();
        void                    add_entry_to_history( Entry* );
        void                    remove_entry_from_history( Entry* );
        void                    clear_history();

        void                    refresh_title()
        {
            if( m_p2entry )
                m_L_title->set_text( m_p2entry->get_title_str() );
        }
        void                    refresh_extra_info();
        void                    refresh_icon()
        {
            if( m_p2entry )
                m_I_icon->set( m_p2entry->get_icon32() );
        }
        void                    refresh_overlay_icon()
        { m_I_overlay->set_visible( m_p2entry && m_p2entry->is_favored() ); }
        void                    refresh_Po_fields();
        void                    refresh_status_date();
        void                    refresh_Bx_editing();
        void                    refresh_CB_spellchecking();

        bool                    is_title_editable() const
        { return( ! m_p2entry->get_date().is_hidden() ); }
        void                    start_title_edit();
        bool                    finish_title_edit();
        void                    apply_title_edit();
        void                    handle_title_changed();
        bool                    handle_title_key_press( GdkEventKey* );
        void                    handle_title_button_clicked();
        bool                    handle_title_click( GdkEventButton* );
        bool                    handle_title_hover( GdkEventCrossing* );
        bool                    handle_title_hover_out( GdkEventCrossing* );

        void                    undo();
        void                    redo();

        void                    prepare_for_hiding();

        void                    toggle_comments();

        void                    set_entries_favorite( VecEntries&&, bool );
        void                    set_entries_todo( VecEntries&&, ElemStatus );
        void                    trash_entries( VecEntries&&, bool );
        void                    set_theme( Theme* );
        void                    refresh_theme();

        Gtk::Popover*           get_popover()
        { return m_Po_entry; }
        TextviewDiaryEdit*      get_textview() { return m_TvDE; }
        //TextbufferDiaryEdit*    get_buffer() { return m_TvDE->m_buffer_edit; }

        void                    hide_popover()
        { if( m_Po_entry ) m_Po_entry->hide(); }

    protected:
        void                    dismiss_entry();
        void                    print();

        void                    handle_spellchecking_changed();
        void                    handle_unit_changed();

        void                    handle_chapter_color_changed();

        // MULTI-THREADING
        void                    start_bg_jobs();
        void                    stop_bg_jobs() { /*TODO*/ }
        void                    handle_bg_jobs_completed();
        void                    destroy_bg_jobs_thread();

        // WIDGETS
        Gtk::MenuButton*        m_MB_entry;
        Gtk::Image*             m_I_icon;
        Gtk::Image*             m_I_overlay;
        Gtk::Label*             m_L_title;
        Gtk::EventBox*          m_EB_title;
        Gtk::Box*               m_Bx_title;
        Gtk::Box*               m_Bx_title_edit;
        EntryClear*             m_E_title;
        Gtk::Button*            m_B_title;
        Gtk::Label*             m_L_extra_info;

        Gtk::Popover*           m_Po_entry;
        Gtk::Label*             m_L_created;
        Gtk::Label*             m_L_edited;
        Gtk::Label*             m_L_status;
        Gtk::Label*             m_L_status_changed;
        Gtk::Label*             m_L_completion;
        Gtk::Label*             m_L_completion_value;
        Gtk::Box*               m_Bx_editing;
        Gtk::RadioButton*       m_RB_not_todo;
        Gtk::RadioButton*       m_RB_todo;
        Gtk::RadioButton*       m_RB_progressed;
        Gtk::RadioButton*       m_RB_done;
        Gtk::RadioButton*       m_RB_canceled;
        Gtk::ToggleButton*      m_TB_favorite;

        Gtk::Box*               m_Bx_unit;
        Gtk::ComboBoxText*      m_CB_unit;
        Gtk::Entry*             m_E_unit;

        Gtk::ComboBoxText*      m_CB_spellcheck;

        Gtk::Button*            m_B_trash;
        Gtk::Button*            m_B_restore;
        Gtk::Button*            m_B_dismiss;

        Gtk::Box*               m_Bx_chapter_color;
        Gtk::ColorButton*       m_ClB_chapter_color;

        Gtk::Stack*             m_St_entry;
        Gtk::ScrolledWindow*    m_SW_entry;
        TextviewDiaryEdit*      m_TvDE;

        // ACTIONS
        Glib::RefPtr< Gtk::Action > m_action_bold;
        Glib::RefPtr< Gtk::Action > m_action_italic;
        Glib::RefPtr< Gtk::Action > m_action_strikethrough;
        Glib::RefPtr< Gtk::Action > m_action_highlight;
        Glib::RefPtr< Gtk::Action > m_action_focus_tag;
        Glib::RefPtr< Gtk::Action > m_action_indent;
        Glib::RefPtr< Gtk::Action > m_action_unindent;
        Glib::RefPtr< Gtk::Action > m_action_add_empty_line_above;
        Glib::RefPtr< Gtk::Action > m_action_remove_empty_line_above;
        Glib::RefPtr< Gtk::Action > m_action_move_line_up;
        Glib::RefPtr< Gtk::Action > m_action_move_line_down;
        Glib::RefPtr< Gtk::Action > m_action_delete_paragraph;
        Glib::RefPtr< Gtk::Action > m_action_time_stamp;

        Action                  m_A_toggle_comments;

        bool                    m_flag_title_edit_in_progress{ false };
        bool                    m_flag_title_applicable{ false };
        bool                    m_flag_index_locked{ false }; // history index

        Entry*                  m_p2entry{ nullptr };

        std::list< Entry* >     m_browsing_history;
        unsigned int            m_bhist_offset{ 0 };  // browsing history index

        // MULTI-THREADING
        sigc::connection        m_connection_bg_jobs;
        std::thread*            m_thread_bg_jobs{ nullptr };
        Glib::Dispatcher        m_dispatcher;
        bool                    m_flag_bg_jobs_queued{ false };

        ParserString            m_parser_word_count; // updates the word count in the bg

    friend class Lifeograph;
};

} // end of namespace LIFEO

#endif
