/* 
   elmo - ELectronic Mail Operator

   Copyright (C) 2003, 2004 rzyjontko

   This program 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; version 2.

   This program 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 this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

   ----------------------------------------------------------------------
   
   Functions related to the file chooser screen.

*/
/****************************************************************************
 *    IMPLEMENTATION HEADERS
 ****************************************************************************/

#include <string.h>

#include "ecurses.h"
#include "choose.h"
#include "linech.h"
#include "interface.h"

/****************************************************************************
 *    IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
 ****************************************************************************/

#define PREAMBLE do {if (win_choose == NULL) return; } while (0)

/****************************************************************************
 *    IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE DATA
 ****************************************************************************/

static WINDOW *win_choose = NULL;

static int column_width;
static int column_count;

static int    item_count;
static char **item_vector;
static int    selected_index;

/****************************************************************************
 *    INTERFACE DATA
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTIONS
 ****************************************************************************/

static int
longest_len (int itemc, char **itemv)
{
        int result = 0;
        int i;
        int len;

        for (i = 0; i < itemc; i++){
                len    = strlen (itemv[i]);
                result = (len > result) ? len : result;
        }
        return result;
}



static void
put_items (void)
{
        linech_t *line;
        int       line_num = 0;
        int       index    = 0;
        int       i;
        int       width, height;

        getmaxyx (win_choose, height, width);

        line = linech_create (width + 1);
        while (index < item_count && line_num <= height){
                linech_clear (line);
                for (i = 0; i < column_count; i++){
                        if (index == item_count)
                                break;
                        if (index == selected_index)
                                line->mask = A_BOLD;
                        linech_add_str_pad (line, item_vector[index], column_width);
                        if (index == selected_index)
                                line->mask = 0;
                        index++;
                }
                window_mvaddchstr (win_choose, line_num, 0, line->str);
                line_num++;
        }
        linech_destroy (line);
}



static void
refresh_me (void)
{
        wnoutrefresh (win_choose);
}


/****************************************************************************
 *    INTERFACE FUNCTIONS
 ****************************************************************************/

int
choose_open (int itemc, char **itemv)
{
        int width;
        int height;
        int top;

        item_count   = itemc;
        item_vector  = itemv;
        column_width = longest_len (itemc, itemv) + 3;

        if (column_width == 0)
                return 1;
  
        column_count = COLS / column_width;

        if (itemc <= column_count){
                width = itemc * column_width;
        }
        else {
                width = column_count * column_width;
        }

        height         = (itemc - 1) / column_count + 1;
        top            = LINES - 2 - height;
        win_choose     = newwin (height, width, top, 0);
        selected_index = 0;

        if (win_choose == NULL)
                return 1;
  
        put_items ();
        refresh_me ();

        return 0;
}


void
choose_close (void)
{
        PREAMBLE;
        delwin (win_choose);
        win_choose = NULL;

        interface_redraw ();
}



void
choose_next (void)
{
        PREAMBLE;

        if (selected_index >= item_count - 1)
                return;

        selected_index++;

        put_items ();
        refresh_me ();
}



void
choose_prev (void)
{
        PREAMBLE;

        if (selected_index == 0)
                return;

        selected_index--;

        put_items ();
        refresh_me ();
}



void
choose_first (void)
{
        PREAMBLE;

        selected_index = 0;
        put_items ();
        refresh_me ();
}



void
choose_last (void)
{
        PREAMBLE;

        selected_index = item_count - 1;
        put_items ();
        refresh_me ();
}



void
choose_cancel (void)
{
        PREAMBLE;

        fprintf (stderr, "%c", '\a');
        
        selected_index = -1;
        choose_close ();
}



int
choose_index (void)
{
        return selected_index;
}


/****************************************************************************
 *    INTERFACE CLASS BODIES
 ****************************************************************************/
/****************************************************************************
 *
 *    END MODULE choose.c
 *
 ****************************************************************************/


syntax highlighted by Code2HTML, v. 0.9.1