/*
 * LL-Dominus: enlace minimo Harbour -> libxlsxwriter.
 * La seleccion y semantica de datos permanecen en TExportXLSX.prg.
 */

#include "hbapi.h"
#include "xlsxwriter.h"

typedef struct
{
   lxw_workbook * workbook;
   lxw_format * header;
   lxw_format * title;
   lxw_format * text;
   lxw_format * integer;
   lxw_format * decimal;
   lxw_format * date;
   lxw_format * datetime;
} LLD_XLSX_CONTEXT;

static LLD_XLSX_CONTEXT * lld_xlsx_context( int iParam )
{
   return ( LLD_XLSX_CONTEXT * ) hb_parptr( iParam );
}

static lxw_worksheet * lld_xlsx_worksheet( int iParam )
{
   return ( lxw_worksheet * ) hb_parptr( iParam );
}

static lxw_format * lld_xlsx_format( LLD_XLSX_CONTEXT * context, int type )
{
   if( ! context )
      return NULL;

   switch( type )
   {
      case 1: return context->header;
      case 2: return context->title;
      case 3: return context->text;
      case 4: return context->integer;
      case 5: return context->decimal;
      case 6: return context->date;
      case 7: return context->datetime;
      default: return NULL;
   }
}

HB_FUNC( LLDXLSXCREATE )
{
   const char * filename = hb_parc( 1 );
   const char * integer_format = hb_parc( 2 );
   const char * decimal_format = hb_parc( 3 );
   const char * date_format = hb_parc( 4 );
   const char * datetime_format = hb_parc( 5 );
   lxw_workbook_options options = { 0 };
   LLD_XLSX_CONTEXT * context;

   if( ! filename || ! *filename )
   {
      hb_retptr( NULL );
      return;
   }

   options.constant_memory = LXW_TRUE;
   context = ( LLD_XLSX_CONTEXT * ) hb_xgrabz( sizeof( LLD_XLSX_CONTEXT ) );
   context->workbook = workbook_new_opt( filename, &options );
   if( ! context->workbook )
   {
      hb_xfree( context );
      hb_retptr( NULL );
      return;
   }

   context->header = workbook_add_format( context->workbook );
   format_set_bold( context->header );
   format_set_pattern( context->header, LXW_PATTERN_SOLID );
   format_set_bg_color( context->header, 0xD9EAF7 );
   format_set_bottom( context->header, LXW_BORDER_THIN );
   format_set_align( context->header, LXW_ALIGN_VERTICAL_CENTER );

   context->title = workbook_add_format( context->workbook );
   format_set_bold( context->title );
   format_set_font_size( context->title, 14 );
   format_set_align( context->title, LXW_ALIGN_CENTER );
   format_set_align( context->title, LXW_ALIGN_VERTICAL_CENTER );

   context->text = workbook_add_format( context->workbook );
   format_set_num_format( context->text, "@" );
   format_set_text_wrap( context->text );

   context->integer = workbook_add_format( context->workbook );
   format_set_num_format( context->integer, integer_format && *integer_format ? integer_format : "0" );

   context->decimal = workbook_add_format( context->workbook );
   format_set_num_format( context->decimal, decimal_format && *decimal_format ? decimal_format : "#,##0.00" );

   context->date = workbook_add_format( context->workbook );
   format_set_num_format( context->date, date_format && *date_format ? date_format : "dd/mm/yyyy" );

   context->datetime = workbook_add_format( context->workbook );
   format_set_num_format( context->datetime, datetime_format && *datetime_format ? datetime_format : "dd/mm/yyyy hh:mm:ss" );

   hb_retptr( context );
}

HB_FUNC( LLDXLSXADDWORKSHEET )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   const char * name = hb_parc( 2 );
   lxw_worksheet * worksheet = context && context->workbook ? workbook_add_worksheet( context->workbook, name ) : NULL;
   hb_retptr( worksheet );
}

HB_FUNC( LLDXLSXWRITESTRING )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 2 );
   lxw_error error = worksheet ? worksheet_write_string( worksheet, ( lxw_row_t ) hb_parnl( 3 ),
      ( lxw_col_t ) hb_parni( 4 ), hb_parc( 5 ), lld_xlsx_format( context, hb_parni( 6 ) ) ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXWRITENUMBER )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 2 );
   lxw_error error = worksheet ? worksheet_write_number( worksheet, ( lxw_row_t ) hb_parnl( 3 ),
      ( lxw_col_t ) hb_parni( 4 ), hb_parnd( 5 ), lld_xlsx_format( context, hb_parni( 6 ) ) ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXWRITEBOOLEAN )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 2 );
   lxw_error error = worksheet ? worksheet_write_boolean( worksheet, ( lxw_row_t ) hb_parnl( 3 ),
      ( lxw_col_t ) hb_parni( 4 ), hb_parl( 5 ), lld_xlsx_format( context, hb_parni( 6 ) ) ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXWRITEDATETIME )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 2 );
   lxw_datetime value;
   lxw_error error;

   value.year = hb_parni( 5 );
   value.month = hb_parni( 6 );
   value.day = hb_parni( 7 );
   value.hour = hb_parni( 8 );
   value.min = hb_parni( 9 );
   value.sec = hb_parnd( 10 );
   error = worksheet ? worksheet_write_datetime( worksheet, ( lxw_row_t ) hb_parnl( 3 ),
      ( lxw_col_t ) hb_parni( 4 ), &value, lld_xlsx_format( context, hb_parni( 11 ) ) ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXWRITEBLANK )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 2 );
   lxw_error error = worksheet ? worksheet_write_blank( worksheet, ( lxw_row_t ) hb_parnl( 3 ),
      ( lxw_col_t ) hb_parni( 4 ), lld_xlsx_format( context, hb_parni( 5 ) ) ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXMERGETITLE )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 2 );
   lxw_error error = worksheet ? worksheet_merge_range( worksheet, ( lxw_row_t ) hb_parnl( 3 ), 0,
      ( lxw_row_t ) hb_parnl( 3 ), ( lxw_col_t ) hb_parni( 4 ), hb_parc( 5 ), context->title ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXFREEZEPANES )
{
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 1 );
   if( worksheet ) worksheet_freeze_panes( worksheet, ( lxw_row_t ) hb_parnl( 2 ), ( lxw_col_t ) hb_parni( 3 ) );
   hb_retl( worksheet != NULL );
}

HB_FUNC( LLDXLSXAUTOFILTER )
{
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 1 );
   lxw_error error = worksheet ? worksheet_autofilter( worksheet, ( lxw_row_t ) hb_parnl( 2 ), 0,
      ( lxw_row_t ) hb_parnl( 3 ), ( lxw_col_t ) hb_parni( 4 ) ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXSETCOLUMN )
{
   lxw_worksheet * worksheet = lld_xlsx_worksheet( 1 );
   lxw_error error = worksheet ? worksheet_set_column( worksheet, ( lxw_col_t ) hb_parni( 2 ),
      ( lxw_col_t ) hb_parni( 2 ), hb_parnd( 3 ), NULL ) : LXW_ERROR_NULL_PARAMETER_IGNORED;
   hb_retl( error == LXW_NO_ERROR );
}

HB_FUNC( LLDXLSXCLOSE )
{
   LLD_XLSX_CONTEXT * context = lld_xlsx_context( 1 );
   lxw_error error;
   if( ! context || ! context->workbook )
   {
      hb_retni( LXW_ERROR_NULL_PARAMETER_IGNORED );
      return;
   }
   error = workbook_close( context->workbook );
   context->workbook = NULL;
   hb_xfree( context );
   hb_retni( ( int ) error );
}
