static char rcsid[] = "@(#)$Id: mailbox.c,v 1.6.6.1 2007/08/24 20:01:56 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.6.6.1 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
 *      or  Kari Hurtta <elm@elmme-mailer.org>
 *****************************************************************************
 * Based on code from src/elm.c. It have following copyright:
 * 
 *  The Elm Mail System 
 *
 * This file and all associated files and documentation:
 *			Copyrighst (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

#include "def_elm.h"
#include "s_elm.h"

DEBUG_VAR(Debug,__FILE__,"ELM");

static void set_mailbox_screen P_((struct menu_context  *page, 
				   struct screen_parts *LOC,
				   struct menu_param  *LIST));


static void set_mailbox_screen(page,LOC, LIST)
     struct menu_context  *page;
     struct screen_parts *LOC;
     struct menu_param  *LIST;
{    
    int   LINES, COLUMNS;	

    menu_get_sizes(page,&LINES, &COLUMNS);

    /* 1)  Title part of screen */

    if (! LOC->title_page)
	LOC->title_page = new_menu_subpage(page,0,4,sb_update_title,LIST);
    else
	menu_subpage_relocate(LOC->title_page,page,0,4);
					  
    /* 2) menu part */

    if (LOC->menu_page && LINES < 14)
	erase_menu_context (&(LOC->menu_page));
    else if (LOC->menu_page)
	menu_subpage_relocate(LOC->menu_page,page,LINES-8,4);
    else if (mini_menu && LINES > 14)
	LOC->menu_page = new_menu_subpage(page,LINES-8,4,
					  sb_show_menu,LIST);
   
    mailbox_screen_common(page,LOC, LIST);	
}


static void check_mailbox_screen P_((struct screen_parts *LOC,
				     struct menu_param *list));
static void check_mailbox_screen(LOC,list)
     struct screen_parts *LOC;
     struct menu_param *list;
{
    /* 1) title page */
    if (menu_resized(LOC->title_page)) {
	DPRINT(Debug,1, (&Debug, "title page resized\n"));

    }
    if (menu_need_redraw(LOC->title_page)) {
	DPRINT(Debug,1, (&Debug, "title page redraw???\n"));
	sb_update_title(LOC->title_page,list);
    }

    if (LOC->menu_page) {
	/* 2) menu page */
	if (menu_resized(LOC->menu_page)) {
	    DPRINT(Debug,1, (&Debug, "menu page resized\n"));
	    
	}
	if (menu_need_redraw(LOC->menu_page)) {
	    DPRINT(Debug,1, (&Debug, "menu page redraw\n"));
	    sb_show_menu(LOC->menu_page,list);
	}
    }

    /* 3) prompt part */
    if (menu_resized(LOC->prompt_page)) {
	DPRINT(Debug,1, (&Debug, "prompt page resized\n"));
    }
    if (menu_need_redraw(LOC->prompt_page)) {
	DPRINT(Debug,7, (&Debug, "prompt page redraw\n"));
	menu_ClearScreen(LOC->prompt_page);

	show_last_error();	/* for those operations that have to
				 * clear the footer except for a message.
				 */
    }

    /* 4) headers part */
    if (menu_resized(LOC->header_page)) {
	DPRINT(Debug,1, (&Debug, "header page resized\n"));
    }
    if (menu_need_redraw(LOC->header_page)) {
	DPRINT(Debug,1, (&Debug, "header page redraw\n"));
	menu_ClearScreen(LOC->header_page);
    }
}

/* returns:

   0  == failure
   1   == OK
   EOF

*/

static int main_messages_loop P_((struct MailboxView  ** cur_mailbox,
				   struct menu_common   * MENU,
				   struct screen_parts  * LOC,
				   struct menu_param    * PARAM,
				   struct menu_context  * page,
				   struct AliasView     * cur_aliaslist));
static int main_messages_loop(cur_mailbox,MENU,LOC,PARAM,page,
			       cur_aliaslist)
     struct MailboxView  ** cur_mailbox;
     struct menu_common   * MENU;
     struct screen_parts  * LOC;
     struct menu_param    * PARAM;
     struct menu_context  *page;
     struct AliasView     * cur_aliaslist;
{
    int ret = 0;

    int auto_assemble = 1;
    int ch = '\0';

    set_mcommon_from_mbxview(MENU,*cur_mailbox);

    get_page(MENU, LOC->header_page);  /* resort_mailbox no longer call get_page() */
    copy_current(MENU,LOC->header_page);
    
    showscreen(page);

    while (1) {

    	int   LINES, COLUMNS;	

	menu_set_default(page);

	menu_get_sizes(page,&LINES, &COLUMNS);

	set_mcommon_from_mbxview(MENU,*cur_mailbox);

	if (menu_resized(page)) {
	    
	    set_mailbox_screen(page,LOC,PARAM);

	    menu_get_sizes(page,&LINES, &COLUMNS);

	    menu_trigger_redraw(page);   /* ? Is needed? */
	}	


#ifdef BACKGROUD_PROCESSES      
	if (handle_sigchld)
	    sigchld_handler();
#endif

	new_mail_check(*cur_mailbox,page, LOC);
	
	/* ??? FIX    Is this correct ?? */
	if (update_view(*cur_mailbox)) {
	    resort_mailbox(*cur_mailbox,1);

	    get_page(MENU, LOC->header_page);  /* resort_mailbox no longer call get_page() */
	    menu_trigger_redraw(LOC->header_page);
	    menu_trigger_redraw(LOC->title_page);
	}

	if (menu_need_redraw(page)) {
	    DPRINT(Debug,7, (&Debug, 
			     "main: pending redraw\n"));
	    
	    showscreen(page);
	}
	check_mailbox_screen(LOC, PARAM);


	
	{   
	    int lin,col;
	    int fh = give_dt_enumerate_as_int(&fragment_handling);

	    menu_PutLineX(LOC->prompt_page,0,0,
			  FRM("%S"),mcommon_give_item(MENU, m_Prompt));
	    menu_GetXYLocation(LOC->prompt_page,&lin,&col);

	    menu_CleartoEOS(LOC->prompt_page);   
	    
	    show_last_error();
	    menu_MoveCursor(LOC->prompt_page,lin,col);

	    /* fragment_handling: 0 == none,
	       1 == manual,
	       2 == auto  */

	    if (auto_assemble && 2 == fh &&
		have_partial(*cur_mailbox)) {
	        ch = 'A';
		auto_assemble = 0;
		
		DPRINT(Debug,4,(&Debug,"Automatic assemble ... \n"));
	    } else
		ch = GetPrompt(LOC->prompt_page);
	
	    /* ? ? ?    resize again? */ 

	    menu_CleartoEOS(LOC->prompt_page);

	    if (isascii(ch) && isprint(ch)) {
		DPRINT(Debug,4,(&Debug, 
				"\nCommand: %c [%d]\n\n", ch, ch));
	    } else {
		DPRINT(Debug,4,(&Debug, 
				"\nCommand: %d\n\n", ch));
	    }
	    
	    set_error("");	/* clear error buffer */
	    
	    menu_MoveCursor(LOC->prompt_page,lin,col);
	}

	ch = mailbox_command(*cur_mailbox,ch, LOC,
			     showmsg_main_cmd,
			     cur_aliaslist,
			     page);
	 

	switch (ch) {
	  case 0:  /* OK */
	      break;
	      
	  case HELP_MARK:
	  case '?' 	:  
	      help(FALSE, page, LOC->prompt_page);

	      break;
	      
	  case '$'    :  {
	      int current;

	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, ElmSet, 
					   ElmResyncFolder,
					   "Resynchronize folder"));
	      FlushBuffer();

	      /* WARNING: Currently resync may quit if resyncing
		 failed ...
	      */
	      resync(cur_mailbox, page, LOC);	    

	      /* FIX MENU pointer ... */
	      set_mcommon_from_mbxview(MENU,*cur_mailbox);

	      current = get_current(*cur_mailbox);
	      get_page(MENU, LOC->header_page);
	  }
	      break;

	  case '|'    :   {
	      int current = get_current(*cur_mailbox);
	      
	      menu_Writechar(LOC->prompt_page,'|');
	      
	      if (current < 1) {
		  lib_error(CATGETS(elm_msg_cat, ElmSet, 
				    ElmNoMailToPipe,
				    "No mail to pipe!"));
		  
	      } else if (give_message_data(*cur_mailbox,current-1,
					   NULL,NULL,NULL,NO_mime_parse)) {
		  
		  /* softkeys_off(); */
		  
		  do_pipe(*cur_mailbox, page,LOC->prompt_page);		


		  /* softkeys_on(); */
	      } else {
		  DPRINT(Debug,3,(&Debug, 
				  "give_message_data [%d] fails",current-1));
	      }
	    }
	      break;

	  case 'A':    {
	      int current = get_current(*cur_mailbox);
	      
	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, 
					   ElmSet, ElmAssemble,
					   "Assemble message fragments"));
	      FlushBuffer();
	      sleep_message();

	      ViewPartial(*cur_mailbox, cur_aliaslist, page);

	      current = get_current(*cur_mailbox);
	      get_page(MENU, LOC->header_page);

	  }
	      break;

	  case 'c'    : {
	      struct MailboxView * new_mailbox = NULL;

	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, 
					   ElmSet, ElmChangeFolder,
					   "Change folder"));
	      /* define_softkeys(CHANGE); */
	      new_mailbox = change_file(*cur_mailbox, cur_aliaslist,
			  page); 

	      if (!new_mailbox)
		  break;

	      /* FIX MENU pointer ... redraw may use it */
	      set_mcommon_from_mbxview(MENU,new_mailbox);
     
	      get_page(MENU, LOC->header_page);  /* resort_mailbox no longer call get_page() */
	
	      menu_trigger_redraw(LOC->header_page);
	      menu_trigger_redraw(LOC->title_page);
	      
	      /* close_cleanup_mbox() may remove mailbox */
	      close_cleanup_mbox(*cur_mailbox);
	     	      
	      free_mailbox(cur_mailbox);
	      *cur_mailbox = new_mailbox;

	      /* define_softkeys(MAIN); */
	  }
	      break;

#ifdef ALLOW_MAILBOX_EDITING
	  case 'e'    :  {
	      int current = get_current(*cur_mailbox);
	      int ul = give_dt_enumerate_as_int(&user_level);

	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, 
					   ElmSet, ElmEditFolder,
					   "Edit folder"));
	      
	      if (ul < 2) {
		  lib_error(CATGETS(elm_msg_cat, ElmSet, 
				    ElmNoFolderEditing,
				    "You are not experienced to use folder editing"));
		  
		  break;
	      }
	      
	      if (current < 1) 
		  lib_error(CATGETS(elm_msg_cat, ElmSet, 
				    ElmFolderIsEmpty,
				    "Folder is empty!"));
	      else
		  edit_mailbox(cur_mailbox, 
			       page);
	      
	  }
	      break;
#else
	  case 'e'    : lib_error(CATGETS(elm_msg_cat, ElmSet, 
					  ElmNoFolderEdit,
					  "Folder editing isn't configured in this version of ELM."));
	      
	      break;
#endif



	  case 'o'    :  {
	      int current = get_current(*cur_mailbox);
	      int i;
	      
	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, ElmSet,
					   ElmOptions,
					   "Options"));
	      if((i=options(*cur_mailbox, cur_aliaslist)) > 0) {

		  current = get_current(*cur_mailbox);
		  get_page(MENU, LOC->header_page);

	      } else if(i < 0)
		  goto OUT;

	      menu_trigger_redraw(page);	/* always fix da screen... */
	  }
	      break;

	  case 'p'    :  {
	      int current = get_current(*cur_mailbox);
	      
	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, ElmSet,
					   ElmPrintMail,
					   "Print mail"));
	      FlushBuffer();

	      if (current < 1) {
		  lib_error(CATGETS(elm_msg_cat, ElmSet, 
				    ElmNoMailToPrint,
				    "No mail to print!"));
		
	      } else if (give_message_data(*cur_mailbox,current-1,
					   NULL,NULL,NULL,NO_mime_parse)) {
		  
		  print_msg(TRUE,*cur_mailbox, page);
		   		 
	      } else {
		  DPRINT(Debug,3,(&Debug, 
				  "give_message_data [%d] fails",current-1));
	      }
	  }
	      break;
	      
	      
	  case 'q'    :  {
	      int idx, mbxcount, found = 0;

	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, ElmSet,
					   ElmQuit,
					   "Quit"));
	      FlushBuffer();

	      mbxcount = get_storage_count(*cur_mailbox);
		
	      for (idx = 0 ; idx < mbxcount; idx++) {
		    int bytes;

		    struct current_storage * storage = 
			get_storage(*cur_mailbox,idx);
	    
		    if (!storage->current_folder)
			continue;


		    if (new_mail_on_folder(storage->current_folder,&bytes)) {
			lib_error(CATGETS(elm_msg_cat, ElmSet, 
					  ElmNewMailQuitCancelled,
					  "New Mail!  Quit canceled..."));
			found++;
		    }
		}

		if (!found) {
		    int r = quit(TRUE, *cur_mailbox,
				 page);		

		    if (EOF == r) {
			ret = EOF;
			goto OUT;
			/* Read failed, control tty died? */		
		    }
		    
		    if (r) {
			ret = 1;
			goto OUT;
		    }

		}
	    }			   
		break;

	  case 'Q'    :  {
	      int idx, mbxcount, found = 0;

	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, ElmSet,
					   ElmQuickQuit,
					   "Quick quit"));
	      FlushBuffer();

	      mbxcount = get_storage_count(*cur_mailbox);
	      
	      for (idx = 0 ; idx < mbxcount; idx++) {
		  int bytes;

		  struct current_storage * storage = 
		      get_storage(*cur_mailbox,idx);
		  
		  if (!storage->current_folder)
		      continue;

		  if (new_mail_on_folder(storage->current_folder,&bytes)) {
		      lib_error(CATGETS(elm_msg_cat, ElmSet, 
					ElmNewMailQuickQuitCancelled,
					"New Mail!  Quick Quit canceled..."));	
		      found++;
		  }
	      }

	      if (!found) {
		  int r = quit(FALSE, *cur_mailbox,
			       page);		
		  
		  
		  if (EOF == r) {
		      ret = EOF;
		      goto OUT;
		      /* Read failed, control tty died? */		
		  }
		  
		  if (r) {
		      ret = 1;
		      goto OUT;
		  }

	      }
	  }
	      break;
	      
	  case 'X'    :  
	      menu_Write_to_screen(LOC->prompt_page,
				   CATGETS(elm_msg_cat, ElmSet,
					   ElmQuickExit,
					   "Quick Exit"));
	      FlushBuffer();

	      goto OUT;
			 
		
	case ctrl('Q') :
	case 'x'    : {   
	    int r;

	    menu_Write_to_screen(LOC->prompt_page,
				 CATGETS(elm_msg_cat, ElmSet,
					 ElmExit,
					 "Exit"));  
	    FlushBuffer();
	    
	    r = exit_mailbox(*cur_mailbox,
			     page);

	    if (EOF == r) {
		ret = EOF;
		goto OUT;
		/* Read failed, control tty died? */		
	    }

	    if (r) {
		ret = 1;
		goto OUT;
	    }


	}
	    break;

	  case EOF :  

	      ret = EOF;
	      goto OUT;
	      /* Read failed, control tty died? */
	     	    	
	  default:
	      lib_error(CATGETS(elm_msg_cat, ElmSet, 
				ElmUnknownCommand,
				"Unknown command. Use '?' for help."));		    
	  }

	  if (menu_need_redraw(page))
	      showscreen(page);

          check_range(MENU,LOC);

	  check_mailbox_screen(LOC, PARAM);
	    
    } /* the BIG while loop! */

 OUT:

    DPRINT(Debug,3,(&Debug, 
		    "main_message_loop() exits with %d\n",ret));


    return ret;
}

/* returns:

   0  == failure
   1   == OK
   EOF

*/

int main_messages_menu(page,req_mfile_vector,cur_aliaslist,check_mode)
     struct menu_context  *page;
     char **req_mfile_vector;
     struct AliasView     * cur_aliaslist;
     enum check_mode      check_mode;
{
    int   ret = 0;

    struct MailboxView   * cur_mailbox = NULL;

    struct menu_common MENU;
    struct screen_parts  LOC  = { NULL, NULL, NULL, NULL };
    struct menu_param  PARAM[elm_mp_COUNT+1] = { 
	{ mp_menu_common, 0 },
	{ mp_integer, 0 },
	{ mp_END,0 }
    };

    set_mcommon_from_mbxview(&MENU,NULL);               /* Clear initially */
    mp_list_set_mcommon(PARAM,elm_mp_menu,&MENU);


    set_mailbox_screen(page,&LOC,PARAM);  
    
    cur_mailbox = initialize_mailbox(req_mfile_vector,page,
				     cur_aliaslist, check_mode);

    if (!cur_mailbox)
	goto fail;

    ret = main_messages_loop(&cur_mailbox,&MENU,&LOC,PARAM,page,
			     cur_aliaslist);


 fail:  
    free_mailbox_screen(&LOC);

    if (cur_mailbox) {   
	DPRINT(Debug,9, (&Debug, 
			 "main_messages_menu: freeing cur_mailbox\n"));
	free_mailbox(&cur_mailbox);
    }

    return ret;
}

/* returns:

   0  == failure
   1   == OK
   EOF

*/

int url_messages_menu(page,url,cur_aliaslist,check_mode)		      
     struct menu_context  * page;
     struct url           * url;
     struct AliasView     * cur_aliaslist;
     enum check_mode      check_mode;
{
    int ret = 0;

    struct MailboxView   * cur_mailbox = NULL;

    struct menu_common MENU;
    struct screen_parts  LOC  = { NULL, NULL, NULL, NULL };
    struct menu_param  PARAM[elm_mp_COUNT+1] = { 
	{ mp_menu_common, 0 },
	{ mp_integer, 0 },
	{ mp_END,0 }
    };

    set_mcommon_from_mbxview(&MENU,NULL);               /* Clear initially */
    mp_list_set_mcommon(PARAM,elm_mp_menu,&MENU);


    set_mailbox_screen(page,&LOC,PARAM);  

    cur_mailbox = initialize_mailbox_from_url(url,page,check_mode,
					      confirm_url);

    if (!cur_mailbox)
	goto fail;

    ret = main_messages_loop(&cur_mailbox,&MENU,&LOC,PARAM,page,
		       cur_aliaslist);
  
 fail:
    free_mailbox_screen(&LOC);

    if (cur_mailbox) {   
	DPRINT(Debug,9, (&Debug, 
			 "url_messages_menu: freeing cur_mailbox\n"));
	free_mailbox(&cur_mailbox);
    }

    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