/********************************************************************
 *                                                                  *
 *      CRISP - Custom Reduced Instruction Set Programmers Editor   *
 *                                                                  *
 *      (C) Paul Fox, 1989                                          *
 *                                                                  *
 *                                                                  *
 *    Please See COPYLEFT notice.                                   *
 *                                                                  *
 ********************************************************************/
# include	"crisp.h"

list	asvd_list;	/* List of files which dont want to be autosaved*/
list	asv_list;	/* List of file-names of auto-saved files which */
			/* need to be deleted when we exit.		*/
int	asv_ext = FALSE;/* TRUE if we have to strip off extension.	*/
int	asv_idle_time;
string	asv_prefix;	/* Filename prefix -- O/S dependent.		*/
string	asv_suffix;	/* Filename suffix.				*/
/**********************************************************************/
/*   Following  says  how  long  to wait before resetting the backup  */
/*   flags for the currently loaded buffers.			      */
/**********************************************************************/
int	rebackup_time;

/**********************************************************************/
/*   Following  is  the period of the rebackup timeout. Default is 2  */
/*   hours.							      */
/**********************************************************************/
int	rebackup_period = 120;

void
main()
{	extern string CRISP_OPSYS;

	switch (CRISP_OPSYS) {
	  case "VMS": 
		asv_prefix = "ASV-";
		asv_suffix = "";
	  case "DOS":
	  	asv_prefix = "";
		asv_suffix = ".asv";
		asv_ext = TRUE;
	  case "UNIX":
		asv_prefix = "@";
		asv_suffix = "@";
	  }
}
void
autosave(string arg)
{	list	l;

	if (!first_time())
		return;
	/***********************************************/
	/*   First  argument  is  the  idle  time  to  */
	/*   set.   The   second   argument   is  the  */
	/*   rebackup timeout.			       */
	/***********************************************/
	if (arg == "")
		arg = "60 120";
	l = split(arg, " ", 1);
	set_idle_default(l[0]);
	rebackup_period = l[1];
	if (rebackup_period)
		rebackup_time = rebackup_period * 60 + time();
	register_macro(REG_IDLE, "autosave_files");
	register_macro(REG_EXIT, "autosave_exit");
}
void
autosave_disable(string filename)
{
	asvd_list += filename;
}
/**********************************************************************/
/*   Function  called  on exit to return the autosave timeout values  */
/*   for the .crinit file.					      */
/**********************************************************************/
string
get_autosave()
{
	return "" + inq_idle_default() + " " + rebackup_period;
}
void
autosave_files()
{
	int	curbuf,
		slash,
		i,
		num_written,
		h, m, s,
		time_now,
		time_since_last,
		nextbuf;
	int	rebackup = FALSE;
	string filename, bufnam;
	extern string CRISP_SLASH;

	/*--------------------------------------------------
	/*   Check to see if user has typed anything recently.
	/*--------------------------------------------------*/
	if (inq_idle_time() < inq_idle_default())
		return;
	/*--------------------------------------------------
	/*   Check to see if its at least idle time since last
	/*   key press.
	/*--------------------------------------------------*/
	time(h, m, s);
	time_now = ((h*60) + m) * 60 + s;
	time_since_last = time_now - asv_idle_time;
	if (time_since_last < inq_idle_default())
		return;
	asv_idle_time = time_now;

	/***********************************************/
	/*   If  the  rebackup  timeout  has  expired  */
	/*   then  set  the  buffer backup flag. This  */
	/*   forces   the  buffer  to  be  backed  up  */
	/*   again.  (Normally  backing up of buffers  */
	/*   only   happens  the  first  time  it  is  */
	/*   saved).				       */
	/***********************************************/
	if (time() >= rebackup_time) {
		rebackup = TRUE;
		rebackup_time = time() + (rebackup_period * 60);
		}
	curbuf = inq_buffer();
	save_position();

	num_written = 0;
	while (1) {
		nextbuf = next_buffer(TRUE);
		set_buffer(nextbuf);
		if (rebackup)
			set_buffer_flags(NULL, BF_BACKUP);
		/***********************************************/
		/*   Write buffer away if its been modified.   */
		/***********************************************/
		if ((inq_buffer_flags() & BF_SYSBUF) == 0 && inq_modified()) {
			/***********************************************/
			/*   Check   to   see   if   file  occurs  in  */
			/*   disabled list.			       */
			/***********************************************/
			inq_names(filename, NULL, bufnam);
			if (re_search(SF_NOT_REGEXP, filename, asvd_list) < 0) {
				/***********************************************/
				/*   Create a file-name for autosaving into.   */
				/***********************************************/
				slash = rindex(filename, CRISP_SLASH);
				filename = substr(filename, 1, slash) +
					   asv_prefix + substr(filename, slash + 1);
				
				/***********************************************/
				/*   Following lines remove any extension.     */
				/***********************************************/
				if (asv_ext) {
					i = rindex(filename, ".");
					if (i > rindex(filename, CRISP_SLASH))
						filename = substr(filename, 1, i - 1);
					}
				filename += asv_suffix;
				message("Autosave %s..", bufnam);
				++ num_written;

				/***********************************************/
				/*   Delete  file  we  are  gonna write first  */
				/*   --  this  ensures under VMS that we dont  */
				/*   end  up  with a million and one versions  */
				/*   of the autosave file.		       */
				/***********************************************/
				remove(filename);
				write_buffer(filename);
				/***********************************************/
				/*   Check  to  see  if  entry  occurs in asv  */
				/*   list.  If  not add it. (So we can delete  */
				/*   file on exit).			       */
				/***********************************************/
				if (re_search(SF_NOT_REGEXP, filename, asv_list) < 0)
					asv_list += filename;
				}
			}
		if (nextbuf == curbuf)
			break;
		}

	set_buffer(curbuf);
	restore_position();
	if (num_written)
 		message("Autosaved %d file%s.", 
			num_written, 
			num_written == 1 ? "" : "s");
}
/**********************************************************************/
/*   This  macro  is  called  when  we  are  about  to  exit.  It is  */
/*   responsible  for  deleting  any  of  the  @  files  we may have  */
/*   accumulated.						      */
/**********************************************************************/
void
autosave_exit()
{
	int n;

	for (n = length_of_list(asv_list); n-- > 0; )
		remove(asv_list[n]);
}
