/* 
   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 <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>

#include "mybox.h"
#include "xmalloc.h"
#include "ask.h"
#include "file.h"
#include "error.h"
#include "read.h"
#include "maildir.h"
#include "gettext.h"
#include "rstring.h"
#include "mail.h"
#include "error.h"
#include "choose.h"
#include "cmd.h"
#include "misc.h"

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

#define REGULAR_FORMAT  "%?%$%# %D %016f (%-06S)  "
#define SENT_FORMAT     "%?%$  %D %016t (%-06S)  "
#define TUTORIAL_FORMAT "%?  "

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

/**
 * this is used when obtaining subdirectories for mailbox
 */
static struct dirent **list;
static int             count;

/**
 * this holds box structure
 */
static ask_t *box_struct = NULL;

/****************************************************************************
 *    INTERFACE DATA
 ****************************************************************************/

/**
 * mailbox path
 */
char *mybox_dir = NULL;


/**
 * wheter to protect mailbox from spam
 */
int mybox_protect = 0;


/**
 * folder line format
 */

char *mybox_format = REGULAR_FORMAT;

/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTIONS
 ****************************************************************************/

static int
select_fun (const struct dirent *entry)
{
        return *entry->d_name != '.';
}


static void
free_list (struct dirent **list, int count)
{
        int i;

        for (i = 0; i < count; i++)
                free (list[i]);

        if (count)
                free (list);

        count = 0;
        list  = NULL;
}


static rstring_t *
get_items (struct dirent **list, int count)
{
        int        i;
        rstring_t *result = rstring_create_size (count + 1);

        for (i = 0; i < count; i++){
                rstring_add (result, list[i]->d_name);
        }

        return result;
}



static char *
box_with_subdir (char *conf, char *def)
{
        char *box;
  
        if (mybox_dir == NULL)
                return NULL;

        box = ask_get_field (box_struct, conf);
        if (box == NULL && def == NULL){
                return NULL;
        }
        else if (box == NULL){
                box = def;
        }

        return file_with_dir (mybox_dir, box);
}


static int
is_box (char *a, char *b)
{
        char *box;

        box = ask_get_field (box_struct, b);
        if (box == NULL)
                box = b;

        if (strcmp (box, a) == 0)
                return 1;
        return 0;
}


static void
remove_protection (char *box, char *noprotect_box)
{
        if (mybox_protect == 0)
                return;
  
        if (is_box (box, noprotect_box)){
                mybox_protect = 0;
        }
}



static void
determine_format (char *box)
{
        if (is_box (box, "sent") || is_box (box, "drafts")
            || is_box (box, "outbox")){
                mybox_format = ask_for_default ("sent_format", NULL);
                if (mybox_format == NULL)
                        mybox_format = SENT_FORMAT;
        }
        else if (is_box (box, "tutorial")){
                mybox_format = TUTORIAL_FORMAT;
        }
        else {
                mybox_format = ask_for_default ("line_format", NULL);
                if (mybox_format == NULL)
                        mybox_format = REGULAR_FORMAT;
        }
}


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

char *
mybox_start (void)
{
        char *box_start;
        char *protect;

        box_struct = ask_select ("mailbox");
        if (box_struct != NULL){
                mybox_dir = ask_get_field (box_struct, "root");
                protect   = ask_get_field (box_struct, "protect");
                if (protect && strcmp (protect, "yes") == 0)
                        mybox_protect = 1;
                else
                        mybox_protect = 0;
                return box_with_subdir ("start", "inbox");
        }
  
        mybox_dir = DATADIR;
        
        box_start = getenv ("MAILDIR");
        if (box_start != NULL)
                return xstrdup (box_start);

        box_start = getenv ("MAIL");
        if (box_start != NULL)
                return xstrdup (box_start);

        box_start = file_with_dir ("/var/mail", getlogin ());
        if (box_start == NULL)
                error_ (0, "%s", _("Couldn't determine user's login name."));
        return box_start;
}



char *
mybox_inbox (void)
{
        return box_with_subdir ("inbox", "inbox");
}



char *
mybox_outbox (void)
{
        return box_with_subdir ("outbox", "outbox");
}


char *
mybox_sent (void)
{
        return box_with_subdir ("sent", "sent");
}



char *
mybox_draft (void)
{
        return box_with_subdir ("drafts", "drafts");
}



char *
mybox_trash (void)
{
        return box_with_subdir ("trash", NULL);
}



char *
mybox_spam (void)
{
        return box_with_subdir ("spam", NULL);
}


void
mybox_create_box (void)
{
        char *newdir;

        if (mybox_dir == NULL){
                error_ (0, _("mailbox not defined"));
                return;
        }

        newdir = read_argument (_("Box name: "), NULL, COMPLETE_FILES,
                                HIDE_NO);
        if (newdir == NULL || *newdir == '\0')
                return;

        newdir = file_with_dir (mybox_dir, newdir);
        maildir_create_dir (newdir);
        xfree (newdir);
}



rstring_t *
mybox_subdirs (void)
{
        if (mybox_dir == NULL)
                return NULL;

        count = scandir (mybox_dir, &list, select_fun, alphasort);
        if (count == -1){
                error_ (errno, "%s", mybox_dir);
                return NULL;
        }

        return get_items (list, count);
}



void
mybox_free_resources (void)
{
        free_list (list, count);
        mybox_dir = NULL;
        if (box_struct)
                ask_destroy (box_struct);
        box_struct = NULL;
}



char *
mybox_select_subdir (void)
{
        char      *answer;
        rstring_t *items;
        int        index;
  
        if (mybox_dir == NULL){
                answer = read_argument (_("Select box: "), NULL,
                                        COMPLETE_FILES, HIDE_NO);
                if (answer == NULL || *answer == '\0')
                        return NULL;
                return xstrdup (answer);
        }

        items = mybox_subdirs ();
        choose_open (items->count, items->array);

        cmd_choose ();

        index = choose_index ();
        if (index == -1){
                rstring_delete (items);
                return NULL;
        }
        answer = file_with_dir (mybox_dir, items->array[index]);
        rstring_delete (items);

        return answer;
}



void
mybox_switching_to (char *box)
{
        char *protect;
        char *seek = strrchr (box, '/');

        if (seek == NULL)
                seek = box;
        else
                seek++;

        if (mybox_dir == NULL)
                return;

        protect = ask_get_field (box_struct, "protect");
        if (protect && strcmp (protect, "yes") == 0)
                mybox_protect = 1;
        else
                mybox_protect = 0;

        remove_protection (seek, "sent");
        remove_protection (seek, "drafts");
        remove_protection (seek, "trash");
        remove_protection (seek, "spam");
        remove_protection (seek, "tutorial");

        determine_format (seek);
}


int
mybox_no_cache (char *box)
{
        char *seek = strrchr (box, '/');

        if (seek == NULL)
                seek = box;
        else
                seek++;

        if (mybox_dir == NULL)
                return 1;

        if (is_box (seek, "outbox"))
                return 1;
        return 0;
}

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


syntax highlighted by Code2HTML, v. 0.9.1