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

   ----------------------------------------------------------------------

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

#include <stdlib.h>

#include "ecurses.h"
#include "frames.h"
#include "color.h"
#include "interface.h"
#include "ask.h"
#include "xmalloc.h"
#include "token.h"

/****************************************************************************
 *    IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
 ****************************************************************************/

struct area {
        struct area *next;
        int          left;
        int          right;
        int          top;
        int          bottom;
};

/****************************************************************************
 *    IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE DATA
 ****************************************************************************/

static WINDOW *frames_win = NULL;

static chtype text_color;
static chtype frame_color;
static chtype fill_color;

struct area *fill_list  = NULL;
struct area *horiz_list = NULL;
struct area *vert_list  = NULL;
struct area *left_list  = NULL;
struct area *right_list = NULL;
struct area *up_list    = NULL;
struct area *down_list  = NULL;
struct area *cross_list = NULL;

static char *fill    = "(25 0 25 0)";
static char *f_horiz = "(0 21 24 21) (0 -8 24 -8)";
static char *f_vert  = "(25 1 25 -1)";
static char *f_left  = "(25 21 25 21) (25 -8 25 -8)";
static char *f_right = "";
static char *f_up    = "";
static char *f_down  = "";
static char *f_cross = "";

static int no_frames;

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


static void
destroy_list (struct area *list)
{
        if (list == NULL)
                return;

        destroy_list (list->next);
        xfree (list);
}


static void
draw_chars (struct area *list, chtype c, chtype color)
{
        int i, j;
        
        if (list == NULL)
                return;

        wattrset (frames_win, color);

        for (i = list->left; i <= list->right; i++){
                for (j = list->top; j <= list->bottom; j++)
                        window_mvaddch (frames_win, j, i, c);
        }

        draw_chars (list->next, c, color);
}


static void
add_to_list (struct area **list, char *str)
{
        int          left, right, top, bottom;
        int          width, height;
        char        *rest;
        struct area *elem;

        left = strtol (str, & rest, 10);
        if (rest == str)
                return;
        top = strtol (rest, & str, 10);
        if (str == rest)
                return;
        right = strtol (str, & rest, 10);
        if (rest == str)
                return;
        bottom = strtol (rest, & str, 10);
        if (str == rest)
                return;

        getmaxyx (frames_win, height, width);

        if (left < 0)
                left += width;
        if (right < 0)
                right += width;
        if (top < 0)
                top += height;
        if (bottom < 0)
                bottom += height;

        if (left < 0 || right < 0 || top < 0 || bottom < 0)
                return;
        
        elem         = xmalloc (sizeof (struct area));
        elem->left   = left;
        elem->right  = right;
        elem->top    = top;
        elem->bottom = bottom;
        elem->next   = *list;

        *list        = elem;
}


static void
create_list (char *str, struct area **list)
{
        int   td;
        char *elem;
        
        if (str == NULL)
                return;

        td = token_open (str, 0, "\\(-?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+\\)", 0);
        while (1){
                elem = token_read_next (td);
                if (elem == NULL)
                        break;
                add_to_list (list, elem + 1);
        }
        token_close (td);
}


/* This file is generated by interface.pl script from interface.desc,
   and inc.in. */
static WINDOW *interface_init (void);
#include "frames.inc"

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


chtype
frames_ch (chtype c)
{
        if (! no_frames)
                return c;

        if (c == ACS_HLINE || c == ACS_TTEE || c == ACS_BTEE)
                return '-';

        if (c == ACS_VLINE || c == ACS_LTEE || c == ACS_RTEE)
                return '|';

        if (c == ACS_PLUS || c == ACS_ULCORNER || c == ACS_URCORNER
            || c == ACS_LLCORNER || c == ACS_LRCORNER)
                return '+';

        return ' ';
}



void
frames_init (void)
{
        frames_win = interface_init ();

        create_list (fill,    & fill_list);
        create_list (f_vert,  & vert_list);
        create_list (f_horiz, & horiz_list);
        create_list (f_left,  & left_list);
        create_list (f_right, & right_list);
        create_list (f_up,    & up_list);
        create_list (f_down,  & down_list);
        create_list (f_cross, & cross_list);

        draw_chars (vert_list,  frames_ch (ACS_VLINE), frame_color);
        draw_chars (horiz_list, frames_ch (ACS_HLINE), frame_color);
        draw_chars (left_list,  frames_ch (ACS_RTEE),  frame_color);
        draw_chars (right_list, frames_ch (ACS_LTEE),  frame_color);
        draw_chars (up_list,    frames_ch (ACS_BTEE),  frame_color);
        draw_chars (down_list,  frames_ch (ACS_TTEE),  frame_color);
        draw_chars (cross_list, frames_ch (ACS_PLUS),  frame_color);
        draw_chars (fill_list,  ' ',                   fill_color);

        touchwin (frames_win);
        wnoutrefresh (frames_win);
}



void
frames_free_resources (void)
{
        if (frames_win)
                delwin (frames_win);
        frames_win = NULL;

        destroy_list (fill_list);
        destroy_list (vert_list);
        destroy_list (horiz_list);
        destroy_list (left_list);
        destroy_list (right_list);
        destroy_list (up_list);
        destroy_list (down_list);
        destroy_list (cross_list);
}

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


syntax highlighted by Code2HTML, v. 0.9.1