/*
 * This file is part of XForms.
 *
 *  XForms is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation; either version 2.1, or
 *  (at your option) any later version.
 *
 *  XForms 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with XForms.  If not, see <http://www.gnu.org/licenses/>.
 */


/**
 * \file sp_choice.c
 *
 *  This file is part of XForms package
 *  Copyright (c) 1996-2002  T.C. Zhao and Mark Overmars
 *  All rights reserved.
 *
 * Settting choice class specific attributes.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "include/forms.h"
#include "fd_main.h"
#include "fd_spec.h"
#include "private/pchoice.h"
#include "spec/choice_spec.h"

extern FD_choiceattrib *create_form_choiceattrib( void );
static FD_choiceattrib *choice_attrib;

static SuperSPEC *choice_spec;
static void show_spec( SuperSPEC * );


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

void *
get_choice_spec_fdform( void )
{
    if ( ! choice_attrib )
    {
        choice_attrib = create_form_choiceattrib( );
        fl_addto_choice( choice_attrib->mode, get_pupmode_string( ) );
        fl_addto_choice( choice_attrib->scope, "local|global" );
        fl_set_choice_item_mode( choice_attrib->mode, 3, FL_PUP_GRAY );
        fl_set_choice_item_mode( choice_attrib->mode, 4, FL_PUP_GRAY );
        fl_set_choice_item_mode( choice_attrib->mode, 5, FL_PUP_GRAY );

        fl_addto_choice( choice_attrib->align,
                         align_name( FL_ALIGN_CENTER, 0 ) );
        fl_addto_choice( choice_attrib->align, align_name( FL_ALIGN_TOP, 0 ) );
        fl_addto_choice( choice_attrib->align,
                         align_name( FL_ALIGN_BOTTOM, 0 ) );
        fl_addto_choice( choice_attrib->align, align_name( FL_ALIGN_LEFT, 0 ) );
        fl_addto_choice( choice_attrib->align, align_name( FL_ALIGN_RIGHT, 0 ) );

        fl_set_browser_dblclick_callback( choice_attrib->content_br,
                                          change_choice_item_cb, 0 );
    }

    return choice_attrib;
}


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

void
choice_spec_restore( FL_OBJECT * ob    FL_UNUSED_ARG,
                     long        data  FL_UNUSED_ARG )
{
    FL_OBJECT *edited = choice_attrib->vdata;

    superspec_to_spec( edited );
    show_spec( get_superspec( edited ) );
    redraw_the_form( 0 );
}


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

static void
show_spec(SuperSPEC * sp)
{
    int i;

    fl_freeze_form( choice_attrib->content_br->form );

    fl_set_button( choice_attrib->new_menuapi, sp->new_menuapi );
    fl_set_counter_value( choice_attrib->val, sp->int_val );
    fl_set_choice_text( choice_attrib->align, align_name( sp->align, 0 ) );
    fl_set_choice( choice_attrib->scope, sp->global_scope + 1 );
    fl_clear_browser( choice_attrib->content_br );

    for ( i = 1; i <= sp->nlines; i++ )
        fl_add_browser_line( choice_attrib->content_br, sp->content[ i ] );

    fl_unfreeze_form( choice_attrib->content_br->form );
}


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

int
set_choice_attrib( FL_OBJECT * ob )
{
    choice_attrib->vdata = ob;
    choice_spec = get_superspec( ob );
    superspec_to_spec( ob );

    fl_set_counter_bounds( choice_attrib->val, 1,
                           choice_spec->nlines >= 1 ? choice_spec->nlines : 1 );
    show_spec( choice_spec );
    return 0;
}


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

void
emit_choice_code( FILE     * fp,
                  FL_OBJECT * ob )
{
    FL_OBJECT *defobj;
    SuperSPEC *sp,
              *defsp;
    int i;

    /* Create a default object */

    defobj = fl_create_choice( ob->type, 0, 0, 0, 0, "" );

    defsp = get_superspec( defobj );
    sp = get_superspec( ob );

    if ( sp->align != defsp->align )
        fprintf( fp, "    fl_set_choice_align( obj, %s );\n",
                 align_name( sp->align, 1 ) );

    if ( sp->nlines < 1 )
        return;

    if ( sp->new_menuapi )
        fprintf( fp, "    fl_set_choice_entries( obj, %s );\n", sp->misc_char );
    else
        for ( i = 1; i <= sp->nlines; i++ )
        {
            fprintf( fp, "    fl_addto_choice( obj, \"%s\" );\n",
                     sp->content[ i ] );
            if ( sp->mode[ i ] != defsp->mode[ i ] )
                fprintf( fp, "    fl_set_choice_item_mode( obj, %d, %s );\n",
                         i, get_pupmode_name( sp->mode[ i ] ) );
            if ( sp->shortcut[ i ] && *sp->shortcut[ i ] )
                fprintf( fp, "    fl_set_choice_item_shortcut( obj, %d, "
                         "\"%s\" );\n", i, sp->shortcut[ i ] );
        }

    if ( sp->int_val != defsp->int_val )
        fprintf( fp, "    fl_set_choice( obj, %d );\n", sp->int_val );
}


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

void
save_choice_attrib( FILE      * fp,
                    FL_OBJECT * ob )
{
    FL_OBJECT *defobj;
    SuperSPEC *defsp, *sp;
    int i;

    /* Create a default object */

    defobj = fl_create_choice( ob->type, 0, 0, 0, 0, "" );

    defsp = get_superspec( defobj );
    sp = get_superspec( ob );

    if ( sp->align != defsp->align )
        fprintf( fp, "    align: %s\n", align_name( sp->align, 0 ) );
    if ( sp->new_menuapi != defsp->new_menuapi )
        fprintf( fp, "    struct: %d\n", sp->new_menuapi );

    for ( i = 1; i <= sp->nlines; i++ )
    {
        fprintf( fp, "    content: %s\n", sp->content[ i ] );
        if ( sp->mode[ i ] != defsp->mode[ i ] )
            fprintf( fp, "    mode: %s\n", get_pupmode_name( sp->mode[ i ] ) );
        if ( sp->shortcut[ i ] && *sp->shortcut[ i ] )
            fprintf( fp, "    shortcut: %s\n", sp->shortcut[ i ] );
    }

    if ( sp->int_val != defsp->int_val )
        fprintf( fp, "    value: %d\n", sp->int_val );
}


/*
 * attributes callbacks
 */

/***************************************
 * Callbacks and freeobj handles for form choiceattrib
 ***************************************/

void
add_choice_item_cb( FL_OBJECT * ob,
                    long        data  FL_UNUSED_ARG )
{
    FD_choiceattrib *ui = ob->form->fdui;
    const char *s = fl_get_input( ui->input );
    const char *sc = fl_get_input( ui->shortcut );
    const char *mode = fl_get_choice_text( ui->mode );
    int i;

    if ( s && *s )
    {
        fl_addto_browser( ui->content_br, s );
        i = fl_addto_choice( ui->vdata, s );
        fl_set_choice_item_shortcut( ui->vdata, i, sc );
        fl_set_choice_item_mode( ui->vdata, i, get_pupmode_value( mode ) );

        if ( fl_get_button( ui->auto_clear ) )
            clear_choice_field_cb( ui->auto_clear, 0 );

        if ( auto_apply )
            redraw_the_form( 0 );

        fl_set_counter_bounds( ui->val, 1,
                               fl_get_choice_maxitems( ui->vdata ) );
    }
}


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

void
replace_choice_item_cb( FL_OBJECT * ob,
                        long        data  FL_UNUSED_ARG )
{
    FD_choiceattrib *ui = ob->form->fdui;
    int i = fl_get_browser( ui->content_br );
    const char *s = fl_get_input( ui->input );
    const char *sc = fl_get_input( ui->shortcut );
    const char *mode = fl_get_choice_text( ui->mode );

    if ( *s && i > 0 )
    {
        fl_replace_browser_line( ui->content_br, i, s );
        fl_replace_choice( ui->vdata, i, s );
        fl_set_choice_item_shortcut( ui->vdata, i, sc );
        fl_set_choice_item_mode( ui->vdata, i, get_pupmode_value( mode ) );

        if ( fl_get_button( ui->auto_clear ) )
            clear_choice_field_cb( ui->auto_clear, 0 );
    }

    if ( auto_apply )
        redraw_the_form( 0 );
}


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

void
delete_choice_item_cb( FL_OBJECT * ob,
                       long        data  FL_UNUSED_ARG )
{
    FD_choiceattrib *ui = ob->form->fdui;
    int i = fl_get_browser( ui->content_br );

    if ( i > 0 )
    {
        fl_delete_browser_line( ui->content_br, i );
        fl_delete_choice( ui->vdata, i );
        if ( auto_apply )
            redraw_the_form( 0 );
    }
}


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

void
change_choice_item_cb( FL_OBJECT * ob,
                       long        data  FL_UNUSED_ARG )
{
    FD_choiceattrib *ui = ob->form->fdui;
    int i = fl_get_browser( ui->content_br );
    FL_OBJECT *edited = ui->vdata;
    FLI_CHOICE_SPEC *sp = edited->spec;

    if ( i > 0 )
    {
        fl_set_input( ui->input, fl_get_browser_line( ui->content_br, i ) );
        if ( sp->shortcut[ i ] )
            fl_set_input( ui->shortcut, sp->shortcut[ i ] );
        fl_set_choice_text( ui->mode, get_pupmode_name( sp->mode[ i ] ) + 3 );
    }
}


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

void
clear_choice_field_cb( FL_OBJECT * ob,
                       long        data  FL_UNUSED_ARG )
{
    FD_choiceattrib *ui = ob->form->fdui;

    fl_set_input( ui->input, "" );
    fl_set_input( ui->shortcut, "" );
    fl_set_choice( ui->mode, 1 );
}


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

void
choice_align_cb( FL_OBJECT * ob,
                 long        data  FL_UNUSED_ARG )
{
    FD_choiceattrib *ui = ob->form->fdui;
    const char *s = fl_get_choice_text( ob );

    fl_set_choice_align( ui->vdata, align_val( s ) );
    if ( auto_apply )
        redraw_the_form( 0 );
}


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

void
choice_val_cb( FL_OBJECT * ob,
               long        data  FL_UNUSED_ARG )
{
    FD_choiceattrib *ui = ob->form->fdui;
    int v = fl_get_counter_value( ob ) + 0.1;

    fl_set_choice( ui->vdata, v );
    if ( auto_apply )
        redraw_the_form( 0 );

}


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

void
use_struct_cb( FL_OBJECT * ob,
               long        data  FL_UNUSED_ARG )
{
    choice_spec->new_menuapi = fl_get_button( ob );
}


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

void
choiceentry_scope_cb( FL_OBJECT * ob,
                      long        data  FL_UNUSED_ARG )
{
    choice_spec->global_scope = ( fl_get_choice( ob ) - 1 ) > 0;
}


#include "spec/choice_spec.c"


/*
 * Local variables:
 * tab-width: 4
 * indent-tabs-mode: nil
 * End:
 */
