/* This file is part of the origami distrubution. (Amiga Port)
 *
 * Source code written by Thomas Hadig in September 1991
 * Version : 1.6.92.1, February 1994
 * (C) 1991-94 by Thomas Hadig
 * may be distributed unchanged ! (see copyright notes)
 */

/*{{{}}}*/
/*{{{  #includes*/
#include <sys/types.h>
#include <time.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#ifdef __SASC
#include <dos.h>
#include <error.h>
#endif
#include <intuition/intuition.h>

#ifdef __SASC
#include <proto/exec.h>
#else
#include <clib/exec_protos.h>
#endif
#include <devices/timer.h>

#define SIGNALS_C
#define I_FOLDFILING_C
#define I_MAIN_C
#define I_KEYBOARD_C
#define I_SCREEN_C
#define I_PROMPT_C
#define I_VIRTUAL_C
#define I_GETMSG_C
#define I_INIT_C
#define I_MESSAGES_C
#define I_DISPLAY_C

#include <origami/origami.h>
#include <origami/exit.h>
/*}}}  */
/*{{{  variables*/
private boolean alarm_running=False;

public boolean timer_running=False, redraw_on_sig=True, do_dump=False;
public int     alarm_time = -1;

extern int     executing_macro;
/*}}}  */

/*{{{  append_sig_token*/
private void append_sig_token(TOKEN t)
 {
  if (redraw_on_sig)
     interrupt_restore=True;
  if (t && sig_count<HISTORY_SIZE)
   {
    sig_macro[sig_count++]=t;
    sig_macro[sig_count]=M_END_MACRO;
    ocl_msg("append signal token %d",t);
   }
 }
/*}}}  */
/*{{{  append_sig_macro*/
#define append_sig_macro(x) append_sig_token((x)+O_EXE_MACRO)
/*}}}  */

/*{{{  check_time_event*/
void check_time_event(void) {}
/*}}}  */
/*{{{  got_alarm*/
public void got_alarm(int a)
 {
  if (alarm_running&&auto_save) append_sig_token (O_AUTO_SAVE);
  ocl_msg("got alarm",0);
 }
/*}}}  */
/*{{{  alarm*/
public void alarm (int ti)
 {
  if (!tr) return;
  if ((ti) && (!timer_running))
   /*{{{  start timer request*/
   {
    tr->tr_node.io_Command = TR_ADDREQUEST;
    tr->tr_node.io_Message.mn_ReplyPort = mpp;
    tr->tr_time.tv_secs = ti;
    tr->tr_time.tv_micro = 0;
    SendIO ((struct IORequest *)tr);
    timer_running=True;
   }
   /*}}}  */
  else if ((!ti) && (timer_running))
   /*{{{  abort timer request*/
   {
    AbortIO ((struct IORequest *)tr);
    WaitIO ((struct IORequest *)tr);
    timer_running=False;
   }
   /*}}}  */
 }
/*}}}  */
/*{{{  timer handling*/
#define time_upd_intervall 45
private boolean timing=False;
private int alarm_delay=0;
private int alarm_missing=0;
private int time_missing=0;

/*{{{  sig_alarm_reached*/
public void sig_alarm_reached(int sig)
 {
  void upd_time(void);
  int delay;

  timer_running=False;
  if (redraw_on_sig)
     interrupt_restore=True;
  ocl_msg("got internal timer",0);
  /*{{{  maybe call autosave*/
  if (alarm_missing==0)
     got_alarm(0);
  /*}}}  */
  /*{{{  maybe update time*/
  if (time_missing<=0 && timing)
   { upd_time();
     time_missing=time_upd_intervall;
   }
  /*}}}  */
  /*{{{  get new delay*/
  if (!timing)
   { alarm_missing=0;
     delay=alarm_delay;
   }
  else if (alarm_missing>time_upd_intervall)
   { alarm_missing-=time_upd_intervall;
     delay=time_upd_intervall;
   }
  else if (alarm_missing)
   { delay=alarm_missing;
     alarm_missing=0;
   }
  else if ((!alarm_delay)||(alarm_delay>time_upd_intervall))
   { if (alarm_delay) alarm_missing=alarm_delay-time_upd_intervall;
     delay=time_upd_intervall;
   }
  else
   { alarm_missing=0;
     delay=alarm_delay;
   }
  /*}}}  */
  time_missing-=delay;
  alarm(delay);
 }
/*}}}  */
/*{{{  timer_handling*/
private void timer_handling(unsigned int delay)
{
  alarm_delay=delay;
  /*{{{  get next timer intervall*/
  if (delay)
   { if (delay<time_upd_intervall)
        alarm_missing=0;
     else
      { alarm_missing=delay /*-time_upd_intervall;*/;
        delay=time_upd_intervall;
      }
   }
  else if (timing)
     delay=time_upd_intervall;
  /*}}}  */
  alarm(delay);
}
/*}}}  */
/*}}}  */
/*{{{  time-timer*/
public char time_str[9];

/*{{{  upd_time*/
void upd_time(void)
{
  if (timing)
   /*{{{  timing*/
   { struct tm *tdat;
     char *s;
     boolean minute;
     time_t t;

     s=time_str;
     *s++=' ';
     *s++='(';
     time(&t);
     tdat=localtime(&t);
     if (tdat)
        for (minute=False,s=time_str+2;;*s++=':')
         { int x;

           x=minute?tdat->tm_min:tdat->tm_hour;
           *s++=hex_digits[x/10];
           *s++=hex_digits[x%10];
           if (minute)
              break;
           minute=True;
         }
     *s++=')';
     *s='\0';
     title_op(CHGTITLE);
   }
   /*}}}  */
  else
     time_str[0]='\0';
}
/*}}}  */
/*{{{  switch_time*/
public int switch_time(boolean on)
{
  boolean old;

  if (timing!=on)
     title_op(CHGTITLE);
  old=timing;
  timing=on;
  upd_time();
  timer_handling(alarm_delay);

  return(old?1:0);
}
/*}}}  */
/*}}}  */
/*{{{  alarm handling*/
/*{{{  set_alarm*/
public void set_alarm(int delay, boolean secs)
 {
  if (tr)
   {
    alarm_running = True;
    if (delay!=0)
     {
      alarm_time=delay;
      if (!secs)
       {
        alarm_time*=60;
        if (alarm_time<MIN_ALARMTIME*60 || alarm_time>MAX_ALARMTIME*60)
        /*{{{  complain and set to default*/
        { message
           ( get_msg
              ( MSG_ARG_FORMAT,
                "["STR_F_ALARM"]",
                MIN_ALARMTIME,
                MAX_ALARMTIME
              )
           );
          alarm_time=NORM_ALARMTIME*60;
        }
        /*}}}  */
       }
     }
    timer_handling(alarm_time);
   }
 }
/*}}}  */
/*{{{  reset_alarm*/
public void reset_alarm(void)
 {
  alarm_running=False;
  timer_handling(0);
 }
/*}}}  */
/*}}}  */

/*{{{  exit_origami*/
public void exit_origami(RETURNS c, unsigned char const *string)
 {
  rcclose();
  if (string) eputs(string);
  close(msg_file);
  end_debug();
  exit (c);
 }
/*}}}  */
/*{{{  init_signals*/
public void init_signals(void)
 {
  timer_handling(0);
  upd_time();
  disable_abort();
 }
/*}}}  */
/*{{{  suspend*/
public void suspend (void) { message(get_msg(M_NO_JOB)); }
/*}}}  */
