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

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

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


#include "../lifeograph.hpp"
#include "widget_datepicker.hpp"


using namespace LIFEO;

// TAG WIDGET ======================================================================================
WidgetDatePicker::WidgetDatePicker( BaseObjectType* o, const Glib::RefPtr<Gtk::Builder>& b )
: Gtk::Entry( o )
{
    initialize();
}

WidgetDatePicker::WidgetDatePicker()
{
    initialize();
}

WidgetDatePicker::~WidgetDatePicker()
{
    // following creates problems for some reason:
    //if( m_Po )
    //    delete m_Po;
}

void
WidgetDatePicker::initialize()
{
    m_Po = new Gtk::Popover( *this );
    m_W_calendar = Gtk::manage( new WidgetCalendar );

    m_Po->set_border_width( 5 );
    m_Po->add( *m_W_calendar );

    m_W_calendar->show();

    set_icon_from_icon_name( "x-office-calendar-symbolic", Gtk::ENTRY_ICON_SECONDARY );

    signal_icon_release().connect( [ this ]( Gtk::EntryIconPosition, const GdkEventButton* ){
            m_Po->is_visible() ? popdown_cal() : popup_cal(); } );

    m_W_calendar->signal_day_selected().connect( [ this ]( date_t date ){
        set_date( date );
        popdown_cal();
        m_Sg_date_set.emit( m_date ); } );
}

void
WidgetDatePicker::set_date( date_t date )
{
    if( Date::is_valid( date ) )
    {
        Lifeograph::START_INTERNAL_OPERATIONS();
        Gtk::Entry::set_text( Date::format_string( date ) );
        get_style_context()->remove_class( "error" );
        m_date = date;
        Lifeograph::FINISH_INTERNAL_OPERATIONS();
    }
}

void
WidgetDatePicker::on_changed()
{
    if( Lifeograph::is_internal_operations_ongoing() )
        return;

    const Ustring text_new{ get_text() };
    bool flag_ok{ false };

    // empty
    if( text_new.empty() )
    {
        m_date = Date::NOT_SET;
    }
    else
    {
        auto result = Date::parse_string( &m_date, text_new );
        if( result == OK )
        {
            m_W_calendar->set_date( m_date );
            flag_ok = true;
        }
        else
            m_date = Date::NOT_SET;
    }

    m_Sg_date_set.emit( m_date );

    if( flag_ok )
        get_style_context()->remove_class( "error" );
    else
        get_style_context()->add_class( "error" );

    Gtk::Entry::on_changed();
}

bool
WidgetDatePicker::on_key_press_event( GdkEventKey* event )
{
    if( ( event->state & ( Gdk::CONTROL_MASK|Gdk::MOD1_MASK|Gdk::SHIFT_MASK ) ) == 0 )
    {
        switch( event->keyval )
        {
            //case GDK_KEY_Return:
            case GDK_KEY_Escape:
                popdown_cal();
                return true;
            case GDK_KEY_Down:
            case GDK_KEY_Up:
                popup_cal();
                return true;
        }
    }
    return Gtk::Entry::on_key_press_event( event );
}

bool
WidgetDatePicker::on_drag_motion( const Glib::RefPtr<Gdk::DragContext>& context,
                                  int x, int y, guint time )
{
    if( Lifeograph::get_dragged_elem() != nullptr )
        if( Lifeograph::get_dragged_elem()->get_type() >= DiaryElement::ET_ENTRY )
        {
            if( Lifeograph::get_dragged_elem()->get_date().is_ordinal() == false )
            {
                context->drag_status( Gdk::ACTION_COPY, time );
                drag_highlight();
                return true;
            }
        }

    drag_unhighlight();  // is called many times unnecessarily :(
    context->drag_refuse( time );
    return false;
}

bool
WidgetDatePicker::on_drag_drop( const Glib::RefPtr< Gdk::DragContext >& context,
                                int x, int y, guint time )
{
    context->drag_finish( true, false, time );

    if( Lifeograph::get_dragged_elem() == nullptr )
        return false;

    auto entry{ Lifeograph::get_dragged_elem() };
    if( entry->get_type() >= DiaryElement::ET_ENTRY )
    {
        set_date( entry->get_date_t() );
        m_Sg_date_set.emit( m_date );
        return true;
    }

    return false;
}

void
WidgetDatePicker::popup_cal()
{
    m_Po->set_pointing_to( get_icon_area( Gtk::ENTRY_ICON_SECONDARY ) );
    m_Po->show();
}

void
WidgetDatePicker::popdown_cal()
{
    m_Po->hide();
}
