static char rcsid[] = "@(#)$Id: thread_messages.c,v 1.3 2006/04/09 07:37:37 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
 *      or  Kari Hurtta <elm@elmme-mailer.org>
 *****************************************************************************/

#include "def_messages.h"
#include "s_me.h"

DEBUG_VAR(Debug,__FILE__,"messages");

#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif

struct mv_thread {
    struct MailboxView       * parent_mailbox;
    
    int                        thread_idx;
};


S_(mt_init_mailbox mt_init_one_thread)
static void mt_init_one_thread P_((struct MailboxView *mbx));

static void mt_init_one_thread(mbx)
     struct MailboxView *mbx;
{

    mbx->u.one_thread = safe_malloc(sizeof (* (mbx->u.one_thread)));
		
    /* bzero is defined hdrs/defs.h */
    bzero((void *)mbx->u.one_thread, sizeof (* (mbx->u.one_thread)));

    mbx->u.one_thread->parent_mailbox     = NULL;
    mbx->u.one_thread->thread_idx         = -1;
}

S_(mt_free_mailbox mt_free_one_thread)
static void mt_free_one_thread P_((struct MailboxView *mbx));
static void mt_free_one_thread(mbx)
     struct MailboxView *mbx;
{
    free(mbx->u.one_thread);
    mbx->u.one_thread = NULL;
}

S_(mt_add_mailbox_storage mt_add_one_thread_storage)
static void mt_add_one_thread_storage P_((struct MailboxView *mailbox,
				       struct current_storage *storage));

static void mt_add_one_thread_storage(mailbox,storage)
     struct MailboxView *mailbox;
     struct current_storage *storage;
{    
    add_storage(mailbox->u.one_thread->parent_mailbox,storage);
}

static void mt_make_one_thread_view P_((struct MailboxView *mailbox));


/* Return 1 if redraw required */
S_(mt_update_view_mailbox mt_update_view_one_thread)
/* Return 1 if redraw required */
static int mt_update_view_one_thread P_((struct MailboxView *mailbox));
static int mt_update_view_one_thread(mailbox)
     struct MailboxView *mailbox;
{
    struct MailboxView * Z = mailbox->u.one_thread->parent_mailbox;
    int count,i;

    int r = update_view(Z);

    if (r) { 
	/* We need updated parent threads -- this assumes that
	   update_mailbox_threads() preserves existing thread numbers 
	*/
	update_mailbox_threads(Z);

	mt_make_one_thread_view(mailbox);
    }   

    return r;
}

S_(mt_get_main_mailbox_folder mt_get_main_one_thread_folder)
static struct folder_info * mt_get_main_one_thread_folder P_((struct 
							      MailboxView 
							      *mailbox));
static struct folder_info * mt_get_main_one_thread_folder(mailbox)
     struct MailboxView *mailbox;
{
    return get_main_folder(mailbox->u.one_thread->parent_mailbox);
}


/* Can be called from signal handler */
S_(mt_get_mailbox_storage mt_get_one_thread_storage)
/* Can be called from signal handler */
static struct current_storage * mt_get_one_thread_storage P_((struct 
							      MailboxView 
							      *mailbox,
							      int i));
/* Can be called from signal handler */
static struct current_storage * mt_get_one_thread_storage(mailbox,i) 
     struct MailboxView *mailbox;
     int i;
{
 
    return get_storage(mailbox->u.one_thread->parent_mailbox,i);
}

/* Can be called from signal handler */
S_(mt_get_mailbox_storage_count mt_get_one_thread_storage_count)
/* Can be called from signal handler */
static int mt_get_one_thread_storage_count P_((struct MailboxView *mailbox));

/* Can be called from signal handler */
static int mt_get_one_thread_storage_count(mailbox) 
     struct MailboxView *mailbox;
{    
    return get_storage_count(mailbox->u.one_thread->parent_mailbox);
}

S_(mt_give_header_mailbox mt_give_header_one_thread)
static struct header_rec * mt_give_header_one_thread(mailbox,index,v)
     struct MailboxView *mailbox;
     int index;
     struct folder_view *v;
{

    struct MailboxView *Z = mailbox->u.one_thread->parent_mailbox;

    if (Z->mailbox_type->magic != MAILBOXTYPE_magic)
	panic("MBX VIEW PANIC",__FILE__,__LINE__,
	      "mt_give_header_one_thread",
	      "Bad type magic number",0);

    return Z->mailbox_type->mt_give_header_it(Z,index, v);
}

struct one_thread_sort {
    struct MailboxView         *parent_mailbox;
};

S_(sdt_give_header_s sdt_give_header_part)
static struct header_rec * sdt_give_header_part P_((struct sort_data *s,
						   struct folder_view *v));
static struct header_rec * sdt_give_header_part(s,v)
     struct sort_data *s;
     struct folder_view *v;
{
    struct MailboxView *Z = s->u.thread->parent_mailbox;

    if (Z->mailbox_type->magic != MAILBOXTYPE_magic)
	panic("MBX VIEW PANIC",__FILE__,__LINE__,
	      "sdt_give_header_part",
	      "Bad type magic number",0);
    
    return Z->mailbox_type->mt_give_header_it(Z,-1, v);
}

static struct sort_data_type thread_sort = {
    SORTDATATYPE_magic,
    sdt_give_header_part
};

S_(mt_sort_mailbox_view mt_sort_one_thread_view)
static void mt_sort_one_thread_view P_((struct MailboxView *mailbox,
				     hdr_compare_func   *func));
static void mt_sort_one_thread_view(mailbox,func)
     struct MailboxView *mailbox;
     hdr_compare_func   *func;
{
    int i;
    struct sort_data * array;

    /* Little dirty ... */
    typedef int (*compar) P_((const void *, const void *));
    compar X = (compar) func;
    
    array = safe_malloc(mailbox->view_len * sizeof (array[0]));

    for (i = 0; i < mailbox->view_len; i++) {
	array[i].w              = mailbox->view[i];
	array[i].t              = mailbox->thread_view;   /* For thread sorting */
	array[i].sort_data_type = &thread_sort;
	array[i].u.thread         = safe_malloc(sizeof (* array[i].u.thread));
	array[i].u.thread->parent_mailbox   = 
	    mailbox->u.one_thread->parent_mailbox;
    }

    qsort(array,mailbox->view_len,sizeof (array[0]), X);
   
    for (i = 0; i < mailbox->view_len; i++) {
	mailbox->view[i] = array[i].w;

	free(array[i].u.thread);
	array[i].u.thread = NULL;
    }

    free(array);
}

S_(mt_give_message_data_mailbox mt_give_message_data_one_thread)
static int mt_give_message_data_one_thread P_((struct MailboxView *mailbox,
					   int index,
					   struct header_rec **ret_header,
					   FILE              **ret_F,
					   struct counter_data *counter,
					   parse_mime_callback *parse_mime,
					   struct folder_view *v));
static int mt_give_message_data_one_thread(mailbox,index,ret_header,ret_F,
				       counter,parse_mime,v)
     struct MailboxView *mailbox;
     int index;
     struct header_rec **ret_header;
     FILE              **ret_F;
     struct counter_data *counter;
     parse_mime_callback *parse_mime;
     struct folder_view *v;
{
    struct MailboxView *Z = mailbox->u.one_thread->parent_mailbox;

    if (Z->mailbox_type->magic != MAILBOXTYPE_magic)
	panic("MBX VIEW PANIC",__FILE__,__LINE__,
	      "mt_give_message_data_one_thread",
	      "Bad type magic number",0);
    
    return Z->mailbox_type->mt_give_message_data_it(Z,index,
						    ret_header,ret_F,
						    counter,parse_mime,
						    v);
}

S_(mt_write_mailbox_info mt_write_one_thread_info)
static void mt_write_one_thread_info P_((FILE *fp, struct MailboxView *mailbox,
				      int s, int cur_idx));
static void mt_write_one_thread_info(fp,mailbox,s,cur_idx)
     FILE *fp; 
     struct MailboxView *mailbox;
     int s;
     int cur_idx;
{
    struct MailboxView *Z = mailbox->u.one_thread->parent_mailbox;
    
    if (Z->mailbox_type->magic != MAILBOXTYPE_magic)
	panic("MBX VIEW PANIC",__FILE__,__LINE__,
	      "mt_write_one_thread_info",
	      "Bad type magic number",0);
    
    Z->mailbox_type->mt_write_it_info(fp,Z,s,cur_idx);
}

S_(mt_mailbox_title mt_one_thread_title)
static struct string * mt_one_thread_title P_((struct MailboxView *mailbox));
static struct string * mt_one_thread_title(mailbox)
     struct MailboxView *mailbox;
{
    struct MailboxView *Z = mailbox->u.one_thread->parent_mailbox;
    CONST struct thread_info *X;

    if (Z->mailbox_type->magic != MAILBOXTYPE_magic)
	panic("MBX VIEW PANIC",__FILE__,__LINE__,
	      "mt_one_thread_title",
	      "Bad type magic number",0);

    X = give_thread_info(Z,mailbox->u.one_thread->thread_idx);
    if (X && X->thread_subject) {
	
	if (string_len(X->thread_subject) < 20) {
	    return format_string(CATGETS(elm_msg_cat, MeSet, 
					 MeThreadTitleName,
					 "Thread \"%S\""),
				 X->thread_subject);
	}

    }
	
    return format_string(CATGETS(elm_msg_cat, MeSet, 
				 MeThreadTitle,"Thread"));
}

S_(mt_make_mailbox_view mt_make_one_thread_view)
static void mt_make_one_thread_view (mailbox)
     struct MailboxView *mailbox;
{
    int * vector;
    struct MailboxView * Z = mailbox->u.one_thread->parent_mailbox;
    
    int count = 0;

    vector = give_thread_message_list(Z,mailbox->u.one_thread->thread_idx,
				      &count);

    if (vector) {
	int i;

	mailbox->view = 
	    safe_realloc(mailbox->view,
			 count * (sizeof ( mailbox->view[0])));

	for (i = 0; i < count; i++) {

	    give_index_number(Z,vector[i], & (mailbox->view[i]));

	    /* Because there is just one thead, thread bumber is 0
	       by defination
	    */
	    mailbox->view[i].thread_number = 0;
	}
	mailbox->view_len = count;

	free(vector);
    }

    if (count < 1) {
	if (mailbox->view)
	    free(mailbox->view);
	mailbox->view     = NULL;
	mailbox->view_len = 0;
    }   
}

S_(mt_add_mailbox_digest mt_add_one_thread_digest)
static void mt_add_one_thread_digest P_((struct MailboxView *mailbox,
				     mime_t *list,
				     time_t received_time,
				     char *env_from,
				     FILE *F,
				     charset_t defcharset));
static void mt_add_one_thread_digest(mailbox, list, received_time, env_from, F,
				  defcharset)
     struct MailboxView *mailbox;
     mime_t *list;
     time_t received_time;
     char *env_from;
     FILE *F;
     charset_t defcharset;
{
    add_digest(mailbox,list,received_time,env_from,F,defcharset);   
}


struct mailbox_type mt_thread = {
    MAILBOXTYPE_magic,
    mt_init_one_thread,
    mt_free_one_thread,
    mt_add_one_thread_storage,
    mt_update_view_one_thread,
    mt_get_main_one_thread_folder,
    mt_get_one_thread_storage,
    mt_get_one_thread_storage_count,
    mt_give_header_one_thread,
    mt_sort_one_thread_view,
    mt_give_message_data_one_thread,
    mt_write_one_thread_info,
    mt_one_thread_title,
    mt_make_one_thread_view,
    mt_add_one_thread_digest
};



struct MailboxView * thread_to_mailbox_view(parent,thread_idx)
       struct MailboxView * parent;
       int thread_idx;
{
    struct MailboxView *ret = malloc_view(&mt_thread);

    if (parent->magic         != MAILBOXVIEW_magic)
	panic("MBX VIEW PANIC",__FILE__,__LINE__,"thread_to_mailbox_view",
	      "Bad magic number",0);
    
    if (parent->mailbox_type->magic != MAILBOXTYPE_magic)
	panic("MBX VIEW PANIC",__FILE__,__LINE__,"thread_to_mailbox_view",
	      "Bad type magic number",0);

    ret->u.one_thread->parent_mailbox = parent;
    ret->u.one_thread->thread_idx     = thread_idx;
    ret->mailbox_type->mt_make_it_view(ret);

    return ret;
}



/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1