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

    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 <cmath>
#include <cairomm/context.h>

#include "../strings.hpp"
#include "../lifeograph.hpp"
#include "table.hpp"


using namespace LIFEO;

// CHART ===========================================================================================
//const std::valarray< double > Table::s_dash_pattern = { 3.0 };

Table::Table()
{
    m_font_main.set_family( "Cantarell" );
    m_font_main.set_size( S_LABEL_H * Pango::SCALE );

    m_font_header.set_family( "Cantarell" );
    m_font_header.set_weight( Pango::WEIGHT_BOLD );
    m_font_header.set_size( S_LABEL_H * Pango::SCALE );
}

void
Table::update_col_geom()
{
    if( m_data.m_columns.empty() ) return;

    m_col_w = m_width_net / m_data.m_columns.size();
}

void
Table::resize( int w, int h )
{
    m_width = w;
    m_height = h;

    m_width_net = w - 2 * S_MARGIN;
    m_height_net = h - 2 * S_MARGIN;

    m_line_c_vis = ( m_height_net / m_line_h ) - 1; // -1 for the header

    update_col_geom();
}

void
Table::calculate_line_h( Glib::RefPtr< Pango::Context > ctx )
{
    auto&& layout{ Pango::Layout::create( ctx ) };
    layout->set_font_description( m_font_header );
    layout->set_text( "XXX" );
    int w_msg, h_msg;
    layout->get_pixel_size( w_msg, h_msg );
    m_line_h = h_msg + 2 * S_CELL_MARGIN;
}

void
Table::scroll( int offset )
{
    if( offset < 0 && ( m_i_line_top + offset ) >= 0 )
        m_i_line_top += offset;
    else
    if( offset > 0 &&
        ( m_i_line_top + offset ) < int( m_line_c_total - m_line_c_vis + S_MIN_LINES ) )
        m_i_line_top += offset;
    else
        return;

    refresh();
}

bool
Table::draw( const Cairo::RefPtr< Cairo::Context >& cr )
{
    // BACKGROUND
    cr->rectangle( 0.0, 0.0, m_width, m_height );
    cr->set_source_rgb( 1.0, 1.0, 1.0 );
    cr->fill();

    auto&& layout{ Pango::Layout::create( cr ) };
    layout->set_font_description( m_font_header );

    // HANDLE NOTHING TO DRAW-CASE SPECIALLY
    if( m_data.m_columns.empty() )
    {
        layout->set_text( _( "ADD COLUMNS" ) );
        int w_msg, h_msg;
        layout->get_pixel_size( w_msg, h_msg );

        cr->set_source_rgb( 0.0, 0.0, 0.0 );
        cr->move_to( ( m_width - w_msg ) / 2 , m_height / 2 );
        layout->show_in_cairo_context( cr );

        return true;
    }

    // HEADER BG FILL
    cr->move_to( S_MARGIN, S_MARGIN );
    cr->rel_line_to( m_width_net, 0 );
    cr->rel_line_to( 0, m_line_h );
    cr->rel_line_to( -m_width_net, 0 );
    cr->close_path();

    cr->set_source_rgb( 0.93, 0.93, 0.93 );
    cr->fill();

    // HOVERED HEADER
    if( m_i_col_cur >= 0 && m_i_line_cur == 0 )
    {
        cr->move_to( S_MARGIN + m_i_col_cur * m_col_w, S_MARGIN );
        cr->rel_line_to( m_col_w, 0 );
        cr->rel_line_to( 0, m_line_h );
        cr->rel_line_to( -m_col_w, 0 );
        cr->close_path();

        cr->set_source_rgb( 0.93, 0.87, 0.87 );
        cr->fill();
    }
    else // HOVERED LINE
    if( m_i_line_cur > 0 &&
        m_i_line_cur < std::min( int( m_line_c_vis ), int( m_line_c_total - m_i_line_top + 1 ) ) )
    {
        cr->move_to( S_MARGIN, S_MARGIN + m_i_line_cur * m_line_h );
        cr->rel_line_to( m_width_net, 0 );
        cr->rel_line_to( 0, m_line_h );
        cr->rel_line_to( -m_width_net, 0 );
        cr->close_path();

        cr->set_source_rgb( 0.96, 0.89, 0.89 );
        cr->fill();
    }

    // VERTICAL LINES
    cr->set_line_width( 1.0 );
    cr->set_source_rgb( 0.5, 0.4, 0.4 );

    for( ListTableColumns::size_type i = 0; i <= m_data.m_columns.size(); i++ )
    {
        // + 0.5 offset needed to get crisp lines:
        cr->move_to( S_MARGIN + i * m_col_w, S_MARGIN );
        cr->rel_line_to( 0, m_height_net );
    }

    // HORIZONTAL LINES
    for( MapTableLines::size_type i = 0; i + m_i_line_top <= m_line_c_total + 1; i++ )
    {
        cr->move_to( S_MARGIN, S_MARGIN + i * m_line_h );
        cr->rel_line_to( m_width_net, 0 );

        if( i > m_line_c_vis )
            break;
    }

    cr->stroke();

    // TEXT
    layout->set_width( ( m_col_w - 2 * S_CELL_MARGIN ) * Pango::SCALE );
    layout->set_ellipsize( Pango::ELLIPSIZE_END );

    cr->set_source_rgb( 0.0, 0.0, 0.0 );

    // COLUMN HEADERS
    layout->set_font_description( m_font_header );
    cr->move_to( S_MARGIN + S_CELL_MARGIN, S_MARGIN + S_CELL_MARGIN );
    int i_col{ 0 };
    for( auto& col : m_data.m_columns )
    {
        if( i_col == m_data.m_i_col_sort )
            layout->set_text( ( m_data.m_f_sort_desc ? "↑ " : "↓ " ) + col->get_name() );
        else
            layout->set_text( col->get_name() );
        layout->show_in_cairo_context( cr );
        cr->rel_move_to( m_col_w, 0.0 );
        i_col++;
    }

    // CELLS
    layout->set_font_description( m_font_main );
    MapTableLines::size_type il = 0;
    for( ; il < ( m_line_c_total - m_i_line_top ); il++ )
    {
        if( ( il + 3 ) * m_line_h > m_height_net )
            break;

        for( ListTableColumns::size_type j = 0; j < m_data.m_columns.size(); j++ )
        {
            layout->set_text( m_data.get_value_str( il + m_i_line_top, j ) );
            cr->move_to( S_MARGIN + S_CELL_MARGIN + j * m_col_w,
                         S_MARGIN + S_CELL_MARGIN + ( il + 1 ) * m_line_h );
            layout->show_in_cairo_context( cr );
        }
    }

    // TOTAL LINE
    layout->set_font_description( m_font_header );
    cr->set_source_rgb( 0.5, 0.5, 0.5 );
    for( ListTableColumns::size_type j = 0; j < m_data.m_columns.size(); j++ )
    {
        layout->set_text( m_data.get_total_value_str( j ) );
        cr->move_to( S_MARGIN + S_CELL_MARGIN + j * m_col_w,
                     S_MARGIN + S_CELL_MARGIN + ( il + 1 ) * m_line_h );
        layout->show_in_cairo_context( cr );
    }

    return true;
}
