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

    Copyright (C) 2007-2018 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/>.

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


#include "panel_main.hpp"
#include "lifeograph.hpp"
#include "app_window.hpp"


using namespace LIFEO;


PanelMain::PanelMain()
{
    auto builder{ Lifeograph::get_builder() };
    builder->get_widget( "St_views", m_St_content );

    builder->get_widget( "Bx_header_title", m_Bx_elem_title );
    builder->get_widget( "EB_header_title", m_eventbox_elem_title );
    builder->get_widget( "L_header_title", m_label_elem_title );
    builder->get_widget( "L_header_subtitle", m_label_elem_extra );

    builder->get_widget( "Bx_header_title_edit", m_Bx_elem_title_edit );
    builder->get_widget_derived( "E_header_title", m_E_elem_title );
    builder->get_widget( "B_header_title", m_B_elem_title );

    builder->get_widget( "MB_elem", m_button_elem );
    builder->get_widget( "B_back", m_button_back );
    builder->get_widget( "I_header_elem", m_image_elem );
    builder->get_widget( "I_header_overlay", m_image_overlay );
    builder->get_widget( "A_header_extra_tools", m_alignment_extra_tools );

    m_eventbox_elem_title->signal_button_press_event().connect(
            sigc::mem_fun( this, &PanelMain::handle_title_click ) );
    m_eventbox_elem_title->signal_enter_notify_event().connect(
            sigc::mem_fun( this, &PanelMain::handle_title_hover ) );
    m_eventbox_elem_title->signal_leave_notify_event().connect(
            sigc::mem_fun( this, &PanelMain::handle_title_hover_out ) );
    m_E_elem_title->signal_changed().connect(
            sigc::mem_fun( this, &PanelMain::handle_entry_title_changed ) );
    m_E_elem_title->signal_key_press_event().connect(
            sigc::mem_fun( this, &PanelMain::handle_entry_title_key_press ) );
//    m_E_elem_title->signal_focus_out_event().connect(
//            sigc::mem_fun( this, &PanelMain::handle_entry_title_focus_out ) );
    m_E_elem_title->signal_activate().connect(
            sigc::mem_fun( this, &PanelMain::apply_title_edit ) );
    m_B_elem_title->signal_clicked().connect(
            sigc::mem_fun( this, &PanelMain::handle_title_button_clicked ) );

    Lifeograph::create_action(
            false, m_action_previous_browsing, "BrowseBack",
            "", "",
            Gtk::AccelKey( GDK_KEY_Left, Gdk::MOD1_MASK ),
            sigc::mem_fun( this, &PanelMain::go_back ) );

    m_button_back->set_related_action( m_action_previous_browsing );

    Lifeograph::p->add_action( "browse_forward", sigc::mem_fun( this, &PanelMain::go_forward ) );
    Lifeograph::p->set_accel_for_action( "app.browse_forward", "<Alt>Right");
}

void
PanelMain::show( ElementViewProto* shower )
{
    PRINT_DEBUG( "====================" );
    PRINT_DEBUG( "DEID: ", shower->get_element()->get_id() );
    PRINT_DEBUG( "====================" );

    if( m_flag_title_edit_in_progress )
        cancel_title_edit();

    // prepare last element for hiding:
    if( m_elem_cur )
        m_elem_cur->prepare_for_hiding();

    m_elem_cur = shower->get_element();
    m_cur_shower = shower;

    // add new element to the history:
    if( ! m_flag_index_locked ) // locked while going back
    {
        if( m_bhist_offset > 0 )
        {
            auto i_end{ m_browsing_history.begin() };

            std::advance( i_end, m_bhist_offset );
            m_browsing_history.erase( m_browsing_history.begin(), i_end );
        }
        m_bhist_offset = 0;
        m_browsing_history.push_front( m_elem_cur );
    }

    Lifeograph::s_internaloperation++;

    // HEADER TEXTS
    m_label_elem_title->set_text( shower->get_title_str() );
    m_label_elem_extra->set_text( shower->get_info_str() );

    // ICON
    m_image_elem->set( shower->get_element()->get_icon32() );
    update_overlay_icon();

    // TOOLBAR
    if( nullptr != ( m_Po_elem = shower->get_popover() ) )
        m_button_elem->set_popover( *m_Po_elem );
    else
        m_button_elem->unset_popover();

    set_extra_tools( shower->get_extra_tools() );

    // CONTENT
    if( m_ptr2widget != shower->get_widget() )
    {
        m_ptr2widget = shower->get_widget();
        m_St_content->set_visible_child( *m_ptr2widget );
    }

    m_flag_title_editable = ( m_cur_shower->is_title_editable() && ! Diary::d->is_read_only() );

    AppWindow::p->panel_diary->show( shower->get_element() );

    Lifeograph::s_internaloperation--;
}

void
PanelMain::handle_login()
{
    m_button_back->set_visible( true );
}

void
PanelMain::handle_logout()
{
    m_button_back->set_visible( false );

    cancel_title_edit(); // checks if title edit is in progress

    clear_history();
}

void
PanelMain::set_extra_tools( Gtk::Widget* tool )
{
    if( m_alignment_extra_tools->get_child() )
        m_alignment_extra_tools->remove();

    if( tool != nullptr )
        m_alignment_extra_tools->add( *tool );
}

void
PanelMain::go_back()
{
    if( ( m_browsing_history.size() - m_bhist_offset ) > 1 )
    {
        auto i = m_browsing_history.begin();
        m_bhist_offset++;
        std::advance( i, m_bhist_offset );

        m_St_content->set_transition_type( Gtk::STACK_TRANSITION_TYPE_SLIDE_RIGHT );

        m_flag_index_locked = true;

        ( *i )->show();

        m_flag_index_locked = false;

        m_St_content->set_transition_type( Gtk::STACK_TRANSITION_TYPE_SLIDE_LEFT );
    }
}

void
PanelMain::go_forward()
{
    if( m_bhist_offset > 0 )
    {
        auto i = m_browsing_history.begin();
        m_bhist_offset--;
        std::advance( i, m_bhist_offset );

        m_flag_index_locked = true;

        ( *i )->show();

        m_flag_index_locked = false;
    }
}

void
PanelMain::remove_element_from_history( DiaryElement* element )
{
    auto remove_element = [ & ]()
    {
        for( auto i = m_browsing_history.begin(); i != m_browsing_history.end(); ++i )
            if( *i == element )
            {
                m_browsing_history.erase( i );
                return true;
            }

        return false;
    };

    while( remove_element() ) continue;
}

void
PanelMain::clear_history()
{
    m_browsing_history.clear();
    m_bhist_offset = 0;
    m_elem_cur = nullptr;
}

void
PanelMain::start_title_edit()
{
    if( m_flag_title_editable )
    {
        m_Bx_elem_title->hide();
        m_Bx_elem_title_edit->show();
        m_E_elem_title->set_text( m_cur_shower->get_title_edit_str() );
        m_E_elem_title->grab_focus();
        m_B_elem_title->set_label( _( "Cancel" ) );

        m_flag_title_applicable = false;
        m_flag_title_edit_in_progress = true;
    }
}

bool
PanelMain::cancel_title_edit()
{
    if( m_flag_title_edit_in_progress )
    {
        m_flag_title_edit_in_progress = false;  // must be first

        m_Bx_elem_title_edit->hide();
        m_Bx_elem_title->show();
        m_label_elem_title->set_text( m_cur_shower->get_title_str() );
    }

    return false; // always false for signal timeout
}

void
PanelMain::handle_entry_title_changed()
{
    if( m_flag_title_edit_in_progress )
    {
        m_flag_title_applicable = m_cur_shower->check_title_applicable(
                m_E_elem_title->get_text() );

        m_B_elem_title->set_label( m_flag_title_applicable ? _( "Apply" ) : _( "Cancel" ) );
    }
}

void
PanelMain::apply_title_edit()
{
    if( m_flag_title_edit_in_progress && m_flag_title_applicable )
    {
        Glib::ustring str( m_E_elem_title->get_text() );

        //m_button_back->grab_focus();    // cancel editing

        m_cur_shower->apply_title( str );

        m_Bx_elem_title_edit->hide();
        m_Bx_elem_title->show();
        m_label_elem_title->set_text( m_cur_shower->get_title_str() );
    }
}

bool
PanelMain::handle_title_click( GdkEventButton* event )
{
    if( m_flag_title_editable && event->button == 1 )
        start_title_edit();
    return false;
}

// cancels editing:
//bool
//PanelMain::handle_entry_title_focus_out( GdkEventFocus* event )
//{
//    Glib::signal_timeout().connect_seconds(
//            sigc::mem_fun( this, &PanelMain::cancel_title_edit ), 1 );
//    //cancel_title_edit();
//
//    return false;
//}

bool
PanelMain::handle_entry_title_key_press( GdkEventKey* event )
{
    if( event->keyval == GDK_KEY_Escape )
        cancel_title_edit();
    return true;
}

bool
PanelMain::handle_title_hover( GdkEventCrossing* )
{
    if( m_flag_title_editable )
        m_label_elem_title->set_markup(
                "<u>" + Glib::Markup::escape_text( m_cur_shower->get_title_str() ) + "</u>" );
    return false;
}

bool
PanelMain::handle_title_hover_out( GdkEventCrossing* )
{
    if( m_flag_title_editable )
        m_label_elem_title->set_text( m_cur_shower->get_title_str() );
    return false;
}

void
PanelMain::handle_title_button_clicked()
{
    if( m_flag_title_applicable )
        apply_title_edit();
    else
        cancel_title_edit();
}
