/*->c.sched */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.bbc"
#include "h.flex"

#include "h.Drawlevel0"


#include "h.def"
#include "h.wos"
#include "h.main"
#include "h.strdef"
#include "h.mym"
#include "h.serial"
#include "h.ram"
#include "h.file"
#include "h.pr"
#include "h.key"
#include "h.script"
#include "h.timex"
#include "h.fsx"
#include "h.dir"
#include "h.view"
#include "h.txfax"
#include "h.config"
#include "h.batch"
#include "h.trans"
#include "h.state"
#include "h.xext"
#include "h.band"
#include "h.con"
#include "h.mess"


#include "h.sched"



#define SXFIRST 2

#define SXRX    1



#define RMINUTE 0
#define RHOUR   1
#define RDAY    2
#define RWEEK   3
#define RMONTH  4


static int rtable[5]=
{
 (60*100),
 (60*60*100),
 (24*60*60*100),
 (7*24*60*60*100),
 (4*7*24*60*60*100),
};



typedef struct schedline    /* size 88 bytes */
{
 int      dirn;             /* number of directory entry */
 int      attempts;         /* attempts at sending       */
 arctime  lastattempt;      /* time of last attempt      */
 arctime  nextattempt;                          /* 24 */
 char     sent;             /* sent ? */
 char     selected;
 char     number[NUMLEN];
 char     after;
 char     hold;                                 /* +32 */

 unsigned int spare1:1;     /* spare */

 unsigned int repeat:1;
 unsigned int sunday:1;
 unsigned int monday:1;
 unsigned int tuesday:1;
 unsigned int wednesday:1;
 unsigned int thursday:1;
 unsigned int friday:1;
 unsigned int saturday:1;
 unsigned int period:4;      /* minute, hour, day, week, month */
 unsigned int every:8;

 unsigned int prefix:1;
 unsigned int voice:1;
 unsigned int fax:1;
 unsigned int data:1;
 unsigned int answer:1;
 unsigned int band:8;
 unsigned int priority:4;


 int          spare[6];                          /* + 24 */

} schedline;


typedef struct schedule
{
 int        entries; 
 int        n;       /* unique number */
 int        handle;
 char       paused;
 char       status;
 char       selstate;
 char       x;

 unsigned int noview:1;


 int        spare[7];
 schedline  line[1]; /* ... */
} schedule;


typedef struct schedulebase
{
 int        sxn;                                    /* how many            */
 int        sxnext;                                 /* unique inc number   */
 schedule   sched[1];
} schedulebase;



static int        modschedule;              /* modifed schedules ? */

static schedulebase * sx;

int            sxmenu;


#define STUNSENT 0
#define STPEND   1
#define STSENT   2


#define SLNONE   0
#define SLSOME   1




static int     pendingtarget;
static int     targetsn;
static int     targetline;
static arctime targettime;
static int     forcenextf; /* flag that allows a send of the 
                                            next fax to be forced */




static void setaftersub(int all);



static schedule * sxnptr(int sn)
{
 schedule * sxq;
 int        entries;

 sxq=&sx->sched[0];
 while(sn--)
 {
  entries=sxq->entries;
  sxq=(schedule *)((char*)sxq+entries*sizeof(schedline)+sizeof(schedule));
 }

 return(sxq);
}


static schedule * sxptr(int sn)
{
 schedule * sxq;
 int        entries;
 int        i;

 sxq=&sx->sched[0];
 for(i=0;i<sx->sxn;i++)
 {
  if(sxq->n==sn) return(sxq);
  entries=sxq->entries;
  sxq=(schedule *)((char*)sxq+entries*sizeof(schedline)+sizeof(schedule));
 }
 return(NULL);
}



static int sxindex(schedule * sxp)
{
 schedule * sxq;
 int        entries;
 int        i;

 sxq=&sx->sched[0];
 for(i=0;i<sx->sxn;i++)
 {
  if(sxq==sxp) break;
  entries=sxq->entries;
  sxq=(schedule *)((char*)sxq+entries*sizeof(schedline)+sizeof(schedule));
 }

 if(i<sx->sxn) return(i);
 else          return(0);
}


    
static void zerohandles(void)
{
 schedule * sxq;
 int        entries;
 int        i;
 int        j;

 sxq=&sx->sched[0];
 for(i=0;i<sx->sxn;i++)
 {
  sxq->handle=0;
  sxq->selstate=SLNONE;
  entries=sxq->entries;

  for(j=0;j<entries;j++)
  {
   sxq->line[j].selected=0;
  }

  sxq=(schedule *)((char*)sxq+entries*sizeof(schedline)+sizeof(schedule));
 }
}



static os_error * addschedulelo(int * sn,int idn)
{
 os_error * err;
 int        size;
 schedule * sxp;

 size=flex_size((flex_ptr)&sx);

 err=flex_extende((flex_ptr)&sx,size+sizeof(schedule));
 if(!err)
 {
  sxp=sxnptr(sx->sxn);
  memset(sxp,0,sizeof(schedule));
  sxp->entries=0;
  *sn=sxp->n=idn;
  sxp->handle=0;
  sxp->paused=0;
  sxp->status=STUNSENT;

  sx->sxn++;
  modschedule=1;
 }
 else report(err);

 return(err);
}



os_error * addschedule(int * sn)
{
 return(addschedulelo(sn,sx->sxnext++));
}







static os_error * delschedule(int sn)
{
 os_error * err;
 schedule * sxp;
 int        size;
 int        entries;
 int        offset;

 err=NULL;

 if(sn)
 {
  sxp=sxptr(sn);
  if(sxp)
  {
   entries=sxp->entries;
   size=entries*sizeof(schedline)+sizeof(schedule);
   offset=(char*)sxp-(char*)sx;
   err=flex_midextende((flex_ptr)&sx,offset+size,-size);
   sx->sxn--;
   modschedule=1;
  }
 }

 return(err);
}



static os_error * addscheduleline(int sn,int dirn,char * number)
{
 os_error * err;
 schedule * sxp;
 int        size;
 int        offset;
 int        entries;

 err=NULL;

 sxp=sxptr(sn);
 if(sxp)
 {
  entries=sxp->entries;
  size=entries*sizeof(schedline)+sizeof(schedule);
  offset=(char*)sxp-(char*)sx;

  err=flex_midextende((flex_ptr)&sx,offset+size,sizeof(schedline));

  memset(&sxp->line[entries],0,sizeof(schedline));
  sxp->line[entries].dirn=dirn;

  if(!dirn) strcpy(sxp->line[entries].number,number);

  getcurtime(&sxp->line[entries].lastattempt);
  sxp->line[entries].nextattempt=sxp->line[entries].lastattempt;

  sxp->line[entries].every=1;

  sxp->line[entries].sunday=sxp->line[entries].monday=
  sxp->line[entries].tuesday=sxp->line[entries].wednesday=
  sxp->line[entries].thursday=sxp->line[entries].friday=
  sxp->line[entries].saturday=1;


  sxp->entries++;
  modschedule=1;
 }
 return(err);
}




os_error * delscheduleline(int sn,int n)
{
 os_error * err;
 schedule * sxp;
 int        size;
 int        offset;
 int        entries;

 err=NULL;

 sxp=sxptr(sn);
 if(sxp)
 {
  entries=sxp->entries;
  size=n*sizeof(schedline)+sizeof(schedule);
  offset=(char*)sxp-(char*)sx;

  err=flex_midextende((flex_ptr)&sx,offset+size,-sizeof(schedline));

  sxp->entries--;
  modschedule=1;
 }

 return(err);
}





/* print summary (xx/xx) */

void summaryschedule(int sn,char * s)
{
 schedule * sxp;
 int        i;
 int        sent;

 if(sn)
 {
  sxp=sxptr(sn);
  if(sxp)
  {
   sent=0;

   for(i=0;i<sxp->entries;i++) if(sxp->line[i].sent) sent++;

   if(sent==sxp->entries && sent) sprintf(s,transtoken("Sent"));
   else
   if(sent==sxp->entries)         sprintf(s,transtoken("New"));
   else                           sprintf(s,"(%d/%d)",sent,sxp->entries);
  }
 }
}



os_error * loadschedule(void)
{
 os_error * err;
 int        fh;
 fstat      f;
 schedule * sxp;
 int        sn;

 modschedule=0;


 err=stat(path(SCHED),&f);
 if(f.object==1 && !err)
 {
  err=flex_alloce((flex_ptr)&sx,f.length);
  if(!err)
  {
   err=fs_open(path(SCHED),'r',&fh);
   if(!err)
   {
    err=fs_read(fh,sx,f.length);
    zerohandles();
   }
   err=fs_close(fh,err);
  }
 }
 else
 {
  err=flex_alloce((flex_ptr)&sx,sizeof(schedulebase));
  if(!err)
  {
   sx->sxn=0;
   sx->sxnext=SXFIRST;
  }
 }

 sxp=sxptr(SXRX);
 if(!sxp)
 {
  err=addschedulelo(&sn,SXRX);
  if(!err)
  {
   sxp=sxptr(SXRX);
   if(sxp)
   {
    sxp->noview=1;
   }
  }
 }

 return(err);
}



os_error * saveschedule(void)
{
 os_error * err;

 err=NULL;

 if(modschedule)
 {
  err=fs_saveblock(path(SCHED),DATA,sx,flex_size((flex_ptr)&sx));
  if(!err) modschedule=0;
 }

 return(err);
}



/*****************************************************************************/


                        /* step between each macro entry in window */
#define TDIRDY   56
                        /* step between top of window and first macro */
#define TDIRFY   12
                        /* height of macro definitions */
#define TDIRHY   48
                        /* x step between entries */
#define TDIRDX   8
#define TDIRPX   8


#define TDIRFW   24
#define TDIRSW   8
#define TDIRTW   23

#define TDIRFXW   TDIRFW*16+2*TDIRPX
#define TDIRSXW   TDIRSW*16+2*TDIRPX
#define TDIRTXW   TDIRTW*16+2*TDIRPX

#define TDIRFX    8
#define TDIRSX    TDIRFXW+TDIRFX+TDIRDX
#define TDIRTX    TDIRSXW+TDIRSX+TDIRDX

#define TDIRWIDTH TDIRTX+TDIRTXW+TDIRDX


static void sxextent(schedule * sxp)
{
 int sety;
 int n;

 if(sxp->handle)
 {
  if(sxp->entries<4) n=4;
  else               n=sxp->entries;

  sety=TDIRFY+TDIRDY*n+TDIRFY;

  extent(sxp->handle,0,-sety,TDIRWIDTH+TDIRDX,0);
 }
}



int getsn(int handle)
{
 int        i;
 schedule * sxq;
 int        entries;

 sxq=&sx->sched[0];

 for(i=0;i<sx->sxn;i++)
 {
  entries=sxq->entries;
  if(sxq->handle==handle) return(sxq->n);

  sxq=(schedule *)((char*)sxq+entries*sizeof(schedline)+sizeof(schedule));
 }
 return(-1);
}




static void redrawschedsub(wimp_redrawstr * redrawstr,int more,schedule * sxp)
{
 int        oy;
 int        ox;
 int        ylo;
 int        yhi;
 int        n;
 int        y;
 int        yp;
 int        entries;
 char       string[32];
 int        col;

 wimpfontstart();

 entries=sxp->entries;

 while(more)
 {
  ox=redrawstr->box.x0-redrawstr->scx;
  oy=redrawstr->box.y1-redrawstr->scy;

  ylo=-(redrawstr->g.y1-oy);            /* small number, top of window */
  yhi=-(redrawstr->g.y0-oy);            /* bigger, bottom of window */

  n=(ylo-TDIRFY)/TDIRDY;
  if(n<0) n=0;
  y=n*TDIRDY+TDIRFY;
  ox+=4;

  while(y<=yhi && n<entries)
  {
   yp=oy-y-4;

   if(sxp->line[n].selected) col=(6<<8)|0;
   else                      col=(1<<8)|7;

   if(sxp->line[n].dirn)
    plinthtext(ox+TDIRFX,yp,TDIRFXW,TDIRHY,diridname(sxp->line[n].dirn),col);
   else
    plinthtext(ox+TDIRFX,yp,TDIRFXW,TDIRHY,sxp->line[n].number,col);


   if(sxp->line[n].hold)
   {
    plinthtext(ox+TDIRSX,yp,TDIRSXW,TDIRHY,transtoken("Hold"),col);
    *string=0;
   }
   else
   if(sxp->line[n].after)
   {
    plinthtext(ox+TDIRSX,yp,TDIRSXW,TDIRHY,transtoken("After"),col);
    writetimedate(string,&sxp->line[n].nextattempt);
   }
   else
   {
    if(sxp->line[n].sent) 
     plinthtext(ox+TDIRSX,yp,TDIRSXW,TDIRHY,transtoken("Finished"),col);
    else
    {
     sprintf(string,"(%d)",sxp->line[n].attempts);
     plinthtext(ox+TDIRSX,yp,TDIRSXW,TDIRHY,string,col);
    }
    writetimedate(string,&sxp->line[n].lastattempt);
   }

   plinthtext(ox+TDIRTX,yp,TDIRTXW,TDIRHY,string,col);

   y+=TDIRDY;
   n++;
  } 
  wimp_get_rectangle(redrawstr,&more);
 }

 wimpfontend();
}


void redrawsched(int sn)
{
 wimp_redrawstr redrawstr;
 int            more;
 schedule     * sxp;

 sxp=sxptr(sn);
 if(sxp)
 {
  redrawstr.w=ewindow;
  wimp_redraw_wind(&redrawstr,&more);
  redrawschedsub(&redrawstr,more,sxp);
 }
}


static void refreshlineentry(schedule * sxp,int n)
{
 wimp_redrawstr r;
 int handle=sxp->handle;
 int more;

 if(handle)
 {
  r.box.x0=0;
  r.box.x1=TDIRWIDTH;
  r.box.y1=-TDIRFY-n*TDIRDY;
  r.box.y0=r.box.y1-TDIRHY-4;
  r.w=handle;

  wimp_update_wind(&r,&more);
  redrawschedsub(&r,more,sxp);
 }
}


static void sxrefresh(schedule * sxp)
{
 if(sxp->handle)
 {
  refreshwindow(sxp->handle);
 }
}


static void refreshviewline(int sn)
{
 int posn;
 view=TXBFILE;
 posn=findviewsn(sn);
 if(posn>=0) viewupdatetexticon(posn);
}



static void schedclearselect(schedule * sxp)
{
 int i;
 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected)
  {
   sxp->line[i].selected=0;
   refreshlineentry(sxp,i);
  }
  sxp->selstate=SLNONE;
 }
}



/* returns number of entries selected, and number of first */

static int schedselected(schedule * sxp,int * k)
{
 int i;
 int n;

 n=0;

 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected)
  {
   if(!n) *k=i;
   n++;
  }
 }
 return(n);
}




void iconsched(int sn)
{
 int        n;
 int        goodn;
 schedule * sxp;
 int        ns;
 int        k;

 sxp=sxptr(sn);
 if(sxp)
 {
  getw(sxp->handle);

  n=(by-mousey-TDIRFY)/TDIRDY;
  goodn=(n>=0 && n<sxp->entries);

  if(buttons==0x1 && goodn)   /* adjust */
  {
   if(sxp->line[n].selected) sxp->line[n].selected=0;
   else                      sxp->line[n].selected=1;


   refreshlineentry(sxp,n);
  }
  else
  if(buttons==0x4)   /* select */
  {
   schedclearselect(sxp);
   if(goodn)
   {
    sxp->line[n].selected=1;
    refreshlineentry(sxp,n);
   }
  }
  else
  if(buttons==0x2)   /* menu */
  {
   if(goodn)
   {
    ns=schedselected(sxp,&k);

    if(ns==1) 
    {
     if(sxp->line[k].selected==2 && k!=n)
     {
      sxp->line[k].selected=0;
      refreshlineentry(sxp,k);
      ns=0;
     }
    }
    if(!ns)
    {
     sxp->line[n].selected=2;
     refreshlineentry(sxp,n);
    }
   }
   popsched(sn);
  }
 }
}


static void delselection(int sn,int all)
{
 int        i;
 schedule * sxp;

 sxp=sxptr(sn);
 if(sxp)
 {
  for(i=0;i<sxp->entries;i++)
  {
   if(sxp->line[i].selected || all)
   {
    delscheduleline(sn,i);
    i--;
   }
  }

  refreshviewline(sn);
  sxrefresh(sxp);
 }
}



void delselectionn(int sn,int i)
{
 schedule * sxp;

 sxp=sxptr(sn);
 if(sxp)
 {
  delscheduleline(sn,i);
  refreshviewline(sn);
  sxrefresh(sxp);
 }
}



static void sentselection(schedule * sxp,int all)
{
 int i;
 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   sxp->line[i].sent=1;
   sxp->line[i].after=0;
   sxp->line[i].hold=0;
   getcurtime(&sxp->line[i].lastattempt);
   sxp->line[i].nextattempt=sxp->line[i].lastattempt;
   refreshlineentry(sxp,i);
   modschedule=1;
  }
 }
 refreshviewline(sxp->n);
}


static void holdselection(schedule * sxp,int all)
{
 int i;
 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   sxp->line[i].hold=1;
   refreshlineentry(sxp,i);
   modschedule=1;
  }
 }
}


static void releaseselection(schedule * sxp,int all)
{
 int i;
 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   sxp->line[i].hold=0;
   refreshlineentry(sxp,i);
   modschedule=1;
  }
 }
}


static void priorityselection(int m4,schedule * sxp,int all)
{
 int i;
 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   sxp->line[i].priority=m4;
  /* refreshlineentry(sxp,i);*/
   modschedule=1;
  }
 }
}


static void setpoppriority(schedule * sxp,int all)
{
 int i;
 int j;
 int x[20];

 for(i=0;i<10;i++) x[i]=i;
// bbc_vdu(4);printf("entries %d",sxp->entries);bbc_vdu(5);

 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   for(j=0;j<MAXPRIORITIES;j++)
   {
    tickst(schedpri_menu,j,j==sxp->line[i].priority);
   }
   break;
  }
 }
}



static int xsn;
static int xprefix;
static int xvoice;
static int xfax;
static int xdata;
static int xband;


static void setpopschedband(void)
{
 int i;

 for(i=-1;i<bands;i++) tickst(band_menu,i+1,i==xband);
}


int setupschedband(int * menu,int item)
{
 setupbandmenu();
 mwpoint(menu,item,(int)band_menu);

 setpopschedband();

 return((int)band_menu);
}



static void bitsselection(int m4,int m5,schedule * sxp,int all)
{
 int i;

 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   switch(m4)
   {
    case 0:
           sxp->line[i].prefix=xprefix^=1;
           break;

    case 1:
           sxp->line[i].voice=xvoice^=1;
           break;

    case 2:
           sxp->line[i].fax=xfax^=1;
           break;

    case 3:
           sxp->line[i].data=xdata^=1;
           break;

    case 4:
           sxp->line[i].answer=0;
           break;

    case 5:
           sxp->line[i].answer=1;
           break;

    case 6:
           if(m5>=0) 
           {
            xband=m5-1;
            sxp->line[i].band=xband;
            setpopschedband();
           }
           break;
   }

  /* refreshlineentry(sxp,i);*/
   modschedule=1;
  }
 }
}





static void setpopbits(schedule * sxp,int all)
{
 int i;

 
// bbc_vdu(4);printf("sxp=%d",sxp->entries);bbc_vdu(5);


 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   tickst(schedbit_menu,0,xprefix=sxp->line[i].prefix);
   tickst(schedbit_menu,1,xvoice =sxp->line[i].voice);
   tickst(schedbit_menu,2,xfax   =sxp->line[i].fax);
   tickst(schedbit_menu,3,xdata  =sxp->line[i].data);
   tickst(schedbit_menu,4,!sxp->line[i].answer);
   tickst(schedbit_menu,5,sxp->line[i].answer);

   xband=sxp->line[i].band;
   if(xband==255) xband=-1;

   break;
  }
 }
}






static void clrselection(schedule * sxp)
{
 schedclearselect(sxp);
}



static void selall(schedule * sxp)
{
 int i;
 for(i=0;i<sxp->entries;i++)
 {
  if(!sxp->line[i].selected)
  {
   sxp->line[i].selected=1;
  }
 }
 sxrefresh(sxp);
}



static void resentselection(schedule * sxp,int all)
{
 int i;
 for(i=0;i<sxp->entries;i++)
 {
  if(sxp->line[i].selected || all)
  {
   sxp->line[i].sent=0;
   sxp->line[i].after=0;
   sxp->line[i].hold=0;
   sxp->line[i].attempts=0;
   getcurtime(&sxp->line[i].lastattempt);
   sxp->line[i].nextattempt=sxp->line[i].lastattempt;
   refreshlineentry(sxp,i);
   modschedule=1;
  }
 }
 refreshviewline(sxp->n);
}




/* delete any schedule lines which belong to this dir entry */

void deleteschedulelines(int dirid)
{
 schedule * sxq;
 int        i;
 int        j;
 int        modded;

 sxq=&sx->sched[0];
 for(i=0;i<sx->sxn;i++)
 {
  modded=0;

  for(j=0;j<sxq->entries;j++)
  {
   if(sxq->line[j].dirn==dirid)
   {
    delscheduleline(sxq->n,j);
    modded=1;
    j--;
   }
  }

  if(modded)
  {
   sxrefresh(sxq);
   refreshviewline(sxq->n);
  }

  sxq=(schedule *)((char*)sxq+sxq->entries*sizeof(schedline)+sizeof(schedule));
 }

 if(!onlinestate()) setuptarget();
}


void closesched(int sn)
{
 schedule * sxp;

 sxp=sxptr(sn);
 if(sxp)
 {
  closedownhandle(&sxp->handle);
  if(!onlinestate()) setuptarget();
  saveconfig();
  refreshviewline(sn);
 }
}



void delschedulehi(int sn)
{
 schedule * sxp;

 sxp=sxptr(sn);
 if(sxp)
 {
  if(sxp->handle) closesched(sn);
  delschedule(sn);
  if(!onlinestate()) setuptarget();
 }
}


#ifdef NEVER

  tx=th=(timenow.hi<<24)|(timenow.lo>>8);
  th/=(3600*24*100)>>8;
  th*=(3600*24*100)>>8;      /* stripped seconds into day */

  tx-=th;                    /* seconds into day */
  tx=(tx<<8)/100;


  if((batbeforetime<bataftertime && (tx>=batbeforetime && tx<=bataftertime)) ||
     (batbeforetime>bataftertime && (tx>=batbeforetime || tx<=bataftertime)))
  {
   th+=(bataftertime*100)>>8;
   timex.hi=(th>>24);
   timex.lo=(th<<8)|0xFF;

   sxp->line[si].after=1;
   sxp->line[si].nextattempt=timex;
  }

#endif







static void setschedbits(schedule * sxp,int si,newbitstr * newbits)
{
 arctime  timenow;
 arctime  timex;
 int      bn;
 int      type;
 int      current;
 int      day;

/* dprintf(0,"ss 1"); */

 if(!sxp || si<0 || si>sxp->entries) return;

 getcurtime(&timenow);
 getdaysec(&timenow,&day,&current);
 timex=timenow;

/* dprintf(0,"ss 2"); */

 if(newbits->priority==BANDOVERNIGHT)
 {

/*dprintf(2,"before %d x=%d after=%d",batbeforetime,current,bataftertime); */

  if(batbeforetime<bataftertime && 
                 (current>=batbeforetime && current<=bataftertime))
  {
   addtimex(&timex,(bataftertime-current)*100,1);
   sxp->line[si].after=1;
   sxp->line[si].nextattempt=timex;
  }
  else
  if(batbeforetime>bataftertime &&
                  (current>=batbeforetime || current<=bataftertime))
  {
   if(current<=bataftertime) addtimex(&timex,(bataftertime-current)*100,1);
   else               addtimex(&timex,(24*3600-current+bataftertime)*100,1);
   sxp->line[si].after=1;
   sxp->line[si].nextattempt=timex;
  }
 }
 else
 if(newbits->priority>BANDIMPORTANT)
 {
/* dprintf(0,"ss 6a"); */

  current=getbandaftertime(newbits->band,newbits->priority,current,day)
                                                                 -current;
/* dprintf(0,"ss 6b"); */

  if(current>0)
  {
   addtimex(&timex,current*100,1);
   sxp->line[si].after=1;
   sxp->line[si].nextattempt=timex;
  }
 }

/* dprintf(0,"ss 3");  */

 sxp->line[si].prefix=newbits->prefix;
 sxp->line[si].band=newbits->band;
 sxp->line[si].priority=newbits->priority;

/* dprintf(0,"ss 4");  */

 if(sxp->noview) /* schedule is not attached to a file */
 {
  if(newbits->override)
  {
   sxp->line[si].voice=newbits->voice;
   sxp->line[si].data=newbits->data;
   sxp->line[si].fax=newbits->fax;
   sxp->line[si].answer=newbits->answer;
  }
  else
  {
   sxp->line[si].voice=((answermode & AVOICE)!=0);
   sxp->line[si].fax=((answermode & AFAX)!=0);
   sxp->line[si].data=((answermode & ADATA)!=0);
   sxp->line[si].answer=1;
  }
 }
 else
 {
/* dprintf(0,"ss 5"); */

  sxp->line[si].answer=0;  /* originate call */

  bn=findviewsn(sxp->n);
  if(bn>=0)
  {
/* dprintf(0,"ss 6"); */

   type=vtable[TXBFILE][bn].stat.type;
   if(type==ASND) sxp->line[si].voice=1;
   else
   if(type==TIFF) sxp->line[si].fax=1;
   else           sxp->line[si].data=1;
  }
 }
}



void addschedhi(int sn,int dirid,char * number,newbitstr * newbits)
{
 schedule * sxp;

 sxp=sxptr(sn);

 if(sxp)
 {
  addscheduleline(sn,dirid,number);

  sxp=sxptr(sn);
  setschedbits(sxp,sxp->entries-1,newbits);

  if(sxp->handle)
  {
   sxextent(sxp);
   refreshlineentry(sxp,sxp->entries-1);
  }
  refreshviewline(sn);
 }
}





int getscheduleinfo(int sn,int n,char * name,int * status)
{
 schedule * sxp;

 sxp=sxptr(sn);

 if(sxp)
 {
  if(n>=0 && n<sxp->entries)
  {
   *status=sxp->line[n].sent|(sxp->line[n].after<<1)|(sxp->line[n].hold<<2);

   if(sxp->line[n].dirn) strcpy(name,diridname(sxp->line[n].dirn));
   else                  strcpy(name,sxp->line[n].number);

   return(1);
  }
 }

 return(0);
}




static void sxpopup(int sn)
{
 wimp_openstr   o;
 schedule     * sxp;

 sxp=sxptr(sn);
 if(sxp)
 {
  o.w=sxp->handle;
  getw(o.w);

  o.box.x0=128+(sn % 5)*vscrlbar;
  o.box.x1=o.box.x0+x1-x0;
  o.box.y1=screeny-2*hscrlbar-(sn % 4)*hscrlbar;
  o.box.y0=o.box.y1-(y1-y0);
  o.y=0;
  o.x=0;
  o.behind=-1;

  wimp_open_wind(&o);
 }
}



os_error * openschedule(int view,int i,int sn)
{
 os_error  * err;
 wimp_wind * wp;
 schedule  * sxp;

 err=NULL;

 if(sn && !(onlinestate() && sn==targetsn))
 {
  sxp=sxptr(sn);
  if(sxp)
  {
   if(sxp->handle)
   {
    forward(sxp->handle);
   }
   else
   {
    wp=windpoi[SX];

    if(sxp->noview) strcpy(wp->title.text,transtoken("Schedule"));
    else            strcpy(wp->title.text,vtable[view][i].name);

    report(wimp_create_wind(wp,&sxp->handle));
    if(sxp->handle)
    {
     sxextent(sxp);
     sxpopup(sn);
     if(!onlinestate()) setuptarget();
    }
   }
  }
 }
 return(err);
}



/* open the rx schedule window */

os_error * rxsched(void)
{
 return(openschedule(0,0,SXRX));
}




/*****************************************************************************/


/* by some mechanism, determine if there is a fax we want to send now */
/* if so, write txdocname, txnumber and txsn                          */

void forcenext(void)
{
 forcenextf=1;
}


void setuptarget(void)
{
 arctime    timenow;
 schedule * sxq;
 int        i;
 int        j;
 int        targetimmediate;
 int        currentimmediate;
 int        targetpriority;
 int        targetattempts;
 int        set;

 getcurtime(&timenow);

 pendingtarget=0;
 forcenextf=0;
 targetimmediate=0; /* compiler */
 targetpriority=0;  /* compiler */
 targetattempts=attempts;

/* dprintf(0,"setup target"); */

 sxq=&sx->sched[0];
 for(i=0;i<sx->sxn;i++)
 {
  for(j=0;j<sxq->entries;j++)
  {
   if(!sxq->paused && !sxq->line[j].sent && !sxq->line[j].hold &&
      !sxq->handle &&  sxq->line[j].attempts<attempts)
   {
    set=0;
    currentimmediate=(cmptimex(&sxq->line[j].nextattempt,&timenow)<0);

    if(!pendingtarget)
    {
     pendingtarget=1;
     set=1;
    }
    else
    {
     /* if target is immediate, and this is immediate, then go on priorities */
     /* else         */
     /* go off times */

     if(currentimmediate && targetimmediate)
     {
      if(sxq->line[j].priority<targetpriority) set=1;
      else
      if(sxq->line[j].priority==targetpriority)
      {
       set=(sxq->line[j].attempts<targetattempts);
      }
     }
     else
     {
      set=(cmptimex(&sxq->line[j].nextattempt,&targettime)<0);
     }
    }

    if(set)
    {
     targettime=sxq->line[j].nextattempt;
     targetsn=sxq->n;
     targetline=j;
     targetpriority=sxq->line[j].priority;
     targetimmediate=currentimmediate;
     targetattempts=sxq->line[j].attempts;
    }
   }
  }
  sxq=(schedule *)((char*)sxq+sxq->entries*sizeof(schedline)+sizeof(schedule));
 }

/* dprintf(0,"target sn=%d",targetsn); */
}




static void setupfile(int sn)
{
 int i;

 i=findviewsn(sn);
 if(i>=0)
 {
  sprintf(txdocname,"%s.%s",xvname(TXBFILE),vtable[TXBFILE][i].name);
  if(vtable[TXBFILE][i].stat.type==TIFF)
  {
   txpages=vtable[TXBFILE][i].tsum.npages;
   txresolution=faxt3res(vtable[TXBFILE][i].tsum.xres,
                         vtable[TXBFILE][i].tsum.yres);

   txwidth=faxt3width(vtable[TXBFILE][i].tsum.maxwidth);
  }
 }
}




/* return 1 if OK, 0 bad target */

int directtarget(int sn)
{
 schedule * sxp;
 int        bn;
 int        type;

 sxp=sxptr(sn);
 if(sxp)
 {
  setupfile(sn);

  strcpy(txname,"");
  strcpy(txnumber,"");

  txsn=targetsn=sn;
  targetline=txsnline=-1;
  txdocuments=1;
  txanswer=0;


  txband=-1;
  txdirn=0;

  txmode=AFAX;
  bn=findviewsn(sn);
  if(bn>=0)
  {
   type=vtable[TXBFILE][bn].stat.type;
   if(type==ASND) txmode=AVOICE;
   else
   if(type==TIFF) txmode=AFAX;
   else           txmode=ADATA;
  }

  return(1);
 }
 return(0);
}




/* given one target+line, return the next for this destination */

static int getnexttarget(int targetsn,int targetline,int * line)
{
 schedule * sxq;
 int        dirn;
 char       number[NUMLEN];
 int        sn;
 int        i;
 int        j;
 int        afax;
 int        adata;
 int        avoice;
 int        limit;


 sxq=sxptr(targetsn);
 if(sxq)
 {
  if((dirn=sxq->line[targetline].dirn)==0)
  {
   strcpy(number,sxq->line[targetline].number);
  }

  afax=sxq->line[targetline].fax;
  adata=sxq->line[targetline].data;
  avoice=sxq->line[targetline].voice;

  /* set sn to the index of this schedule */

  sn=sxindex(sxq);

  for(i=0;i<=sx->sxn;i++)
  {
   if(i==sx->sxn) limit=targetline;
   else           limit=sxq->entries;

   for(j=((i==0)?(targetline+1):0);j<limit;j++)
   {
    if(!sxq->paused && !sxq->line[j].sent && !sxq->line[j].hold &&
       !sxq->handle &&  sxq->line[j].attempts<attempts)
    {
     if((sxq->line[j].dirn==dirn && dirn) ||
         (!dirn && !strcmp(number,sxq->line[j].number)))
     {
      if(sxq->line[j].fax==afax && sxq->line[j].data==adata &&
                                   sxq->line[j].voice==avoice)
      {
       *line=j;
       return(sxq->n);
      }
     }
    }
   }

   sn++;
   if(sn<sx->sxn)
    sxq=
     (schedule *)((char*)sxq+sxq->entries*sizeof(schedline)+sizeof(schedule));
   else
   {
    sxq=&sx->sched[0];
    sn=0;
   }
  }
 }

 *line=targetline;
 return(targetsn);
}




/* how many files of this type are there for the current target */

static int txtargetfiles(void)
{
 int sn;
 int line;
 int nsn;
 int nline;
 int n;

 sn=targetsn;
 line=targetline;
 n=1;

 while(1)
 {
  nsn=getnexttarget(sn,line,&nline);

  if(nsn==targetsn && nline==targetline) break;
  n++;
  sn=nsn;
  line=nline;
 }

 return(n);
}



int txnexttarget(void)
{
 targetsn=getnexttarget(targetsn,targetline,&targetline);

 setupfile(targetsn);

 txsn=targetsn;
 txsnline=targetline;

 return(1);
}



int txfindtarget(void)
{
 arctime    curtime;
 schedule * sxp;
 int        txprefix;

 if(pendingtarget)
 {
  getcurtime(&curtime);
/*  dprintf(7,"cur=%d tar=%d",curtime.lo,targettime.lo); */

  if((cmptimex(&targettime,&curtime)<=0) || forcenextf)
  {
   forcenextf=0;
   sxp=sxptr(targetsn);

   if(sxp)
   {
    txprefix=sxp->line[targetline].prefix;
    txband=sxp->line[targetline].band;
    txdirn=sxp->line[targetline].dirn;
    txanswer=sxp->line[targetline].answer;
    txmode=0;
    if(sxp->line[targetline].voice) txmode|=AVOICE;
    if(sxp->line[targetline].fax)   txmode|=AFAX;
    if(sxp->line[targetline].data)  txmode|=ADATA;

    if(txdirn)
    {
     diridnumber(sxp->line[targetline].dirn,txnumber,txprefix);
     strcpy(txname,diridname(sxp->line[targetline].dirn));
    }
    else
    {
     getnumber(sxp->line[targetline].number,txnumber,0,txprefix);
     strcpy(txname,sxp->line[targetline].number);
    }

    setupfile(targetsn);

    txsn=targetsn;
    txsnline=targetline;

    if(sxp->noview) txdocuments=0;
    else            txdocuments=txtargetfiles();

   /* dprintf(0,"docs=%d",txdocuments); */

    return(1);
   }
  }
 }
 return(0);
}




static void repeatstuff(schedline * line)
{
 arctime timex;
 int     delay;
 int     i;
 int     day;
 int     secs;

 if(line->repeat)
 {
  timex=line->lastattempt;

  delay=line->every*rtable[line->period];

  for(i=0;i<7;i++)
  {
   addtimex(&timex,delay,1);

   getdaysec(&timex,&day,&secs);

   if((day==6 && line->sunday) ||
      (day==0 && line->monday) ||
      (day==1 && line->tuesday) ||
      (day==2 && line->wednesday) ||
      (day==3 && line->thursday) ||
      (day==4 && line->friday) ||
      (day==5 && line->saturday)) break;

   delay=(3600*24*100);
  }

  if(i<7)
  {
   line->sent=0;
   line->after=1;
   line->attempts=0;
   line->nextattempt=timex;
  }
 }
}



/* called by state machine if a dial attempt fails     */
/* called by tx document close if error during sending */

void schedaddattempt(void)
{
 arctime    curtime;
 schedule * sxp;

 getcurtime(&curtime);

 sxp=sxptr(targetsn);
 if(sxp)
 {
  if(targetline>=0)
  {
   if(!sxp->line[targetline].sent)
   {
    sxp->line[targetline].attempts++;
    sxp->line[targetline].after=0;
    sxp->line[targetline].lastattempt=curtime;
    sxp->line[targetline].nextattempt=curtime;
    addtimex(&sxp->line[targetline].nextattempt,ardelay,1);

    if(sxp->line[targetline].attempts>=attempts) 
                               repeatstuff(&sxp->line[targetline]);
   }
  }
  refreshviewline(targetsn);
 }
 setuptarget();
 modschedule=1;
 consent(0);

 messageout(FaxFailed,0,targetsn,targetline);
}



int noviewsched(int sn)
{
 schedule * sxp;

 sxp=sxptr(sn);

 if(sxp)
 {
  return(sxp->noview);
 }

 return(0);
}



/* called by tx document when document sucessfully sent */

void schedsentdoc(void)
{
 arctime    curtime;
 schedule * sxp;
 int        i;
 int        sent;
 int        entries;
 int        posn;

 getcurtime(&curtime);

 sxp=sxptr(targetsn);
 if(sxp)
 {
  if(targetline>=0)
  {
   sxp->line[targetline].attempts++;
   sxp->line[targetline].sent=1;
   sxp->line[targetline].after=0;
   sxp->line[targetline].lastattempt=curtime;

   repeatstuff(&sxp->line[targetline]);

   entries=sxp->entries;
   sent=0;
   for(i=0;i<entries;i++)
    if(sxp->line[i].sent) sent++;

   if(!sxp->noview)
   {
    if(sent==entries && sent && autoremove)
    {
     view=TXBFILE;
     posn=findviewsn(targetsn);
     deleteentry(posn,1);
    }
    else
    {
     refreshviewline(targetsn);
    }
   }
  }
 }
 setuptarget();
 modschedule=1;
 consent(1);
 messageout(FaxSent,0,targetsn,targetline);
}


void holdall(int hold)
{
 schedule * sxq;
 int        i;
 int        j;

 sxq=&sx->sched[0];
 for(i=0;i<sx->sxn;i++)
 {
  for(j=0;j<sxq->entries;j++)
  {
   if(!sxq->paused && !sxq->line[j].sent && 
      !sxq->handle &&  sxq->line[j].attempts<attempts)
   {
    sxq->line[j].hold=hold;
    modschedule=1;
   }
  }
  sxq=(schedule *)((char*)sxq+sxq->entries*sizeof(schedline)+sizeof(schedule));
 }

 if(!onlinestate()) setuptarget();
}


/* puts the target into hold state */

void holdtarget(void)
{
 schedule * sxp;

 if(pendingtarget)
 {
  sxp=sxptr(targetsn);
  if(sxp)
  {
   sxp->line[targetline].hold=1;
   modschedule=1;
  }
 }
}


int unsentn(void)
{
 schedule * sxq;
 int        i;
 int        j;
 int        unsent;

 unsent=0;

 sxq=&sx->sched[0];
 for(i=0;i<sx->sxn;i++)
 {
  for(j=0;j<sxq->entries;j++)
  {
   if(!sxq->paused && !sxq->line[j].sent && !sxq->line[j].hold &&
      !sxq->handle &&  sxq->line[j].attempts<attempts)
   {
    unsent++;
   }
  }
  sxq=(schedule *)((char*)sxq+sxq->entries*sizeof(schedline)+sizeof(schedule));
 }

 return(unsent);
}

void checkunsent(int hold)
{
 if(hold) holdall(1);
 else
 if(unsentn() && unsentwarn)
 {
  if(confirm(CONYN,"{HOLD}"))
  {
   holdall(1);
  }
 }
}



/****************************************************************************/

/*
void clearqueue(int fp)
{
 setuptarget();
 USE(fp);
}


void setupqueue(int fp)
{



}


int addtoqueue(int fp)
{



}
*/


/****************************************************************************/

static void setpopsched(int sn)
{
 schedule     * sxp;
 int            n;
 int            k;
 char         * p;

 sxp=sxptr(sn);
 if(sxp)
 {
  getw(sxp->handle);

  n=schedselected(sxp,&k);

  if(n>1)
   strcpy(menuaddr(schedule_menu,1),transtoken("SCH00"));
  else
  {
   if(n==1)
   {
    if(sxp->line[k].dirn) p=diridname(sxp->line[k].dirn);
    else                  p=sxp->line[k].number;
   }
   else p="";

   sprintf(menuaddr(schedule_menu,1),"%s '%s'",transtoken("SCH01"),p);
  }

  unshadest(schedule_menu,1,n>0);

  setpoppriority(sxp,0);
  setpopbits(sxp,0);
 }
}



static void decodesel(int m3,int m4,int m5,int all)
{
 switch(m3)
 {
  case 0:         /* delete */
         delselection(sxmenu,all);
         break;

  case 1:
         sentselection(sxptr(sxmenu),all);
         break;

  case 2:
         resentselection(sxptr(sxmenu),all);
         break;


  case 4:
         holdselection(sxptr(sxmenu),all);
         break;

  case 5:
         releaseselection(sxptr(sxmenu),all);
         break;

  case 6:
         if(m4>=0) priorityselection(m4,sxptr(sxmenu),all);
         break;

  case 7:
         bitsselection(m4,m5,sxptr(sxmenu),all);
         break;

 }
}



void decodesched(int m2,int m3,int m4,int m5)
{
 switch(m2)
 {
  case 0:
         decodedial(m3);
         break;

  case 1:
         decodesel(m3,m4,m5,0);
         break;

  case 2:
         selall(sxptr(sxmenu));
         break;

  case 3:
         clrselection(sxptr(sxmenu));
         break;

 }

 m3=m4=m5;
 setpopsched(sxmenu);
}



/* allow user to have a menu on the whole fax          */
/* schedule window is closed at this point, in general */

void scheddecodebatchdial(int m,int sn)
{
 sxmenu=sn;
 decodedial(m);
}


void scheddecodebatch(int m3,int m4,int m5,int sn)
{
 sxmenu=sn;
 decodesel(m3,m4,m5,1);
}

void scheddecodebatchafter(int sn)
{
 sxmenu=sn;
 setaftersub(1);
}


void setpopbatchsched(int sn)
{
 schedule * sxp;

 xsn=sn;
 sxp=sxptr(sn);
 if(sxp)
 {
  setpoppriority(sxp,1);
  setpopbits(sxp,1);
 }
}


void popsched(int sn)
{
 sxmenu=sn;
 setpopsched(sn);
 popmenu(schedule_menu);
}

/*****************************************************************************/

static arctime    sxtimex;
static setafterfn setafterf;

static int        xrepeat;
static int        xevery;
static int        xperiod;
static int        xsunday;
static int        xmonday;
static int        xtuesday;
static int        xwednesday;
static int        xthursday;
static int        xfriday;
static int        xsaturday;



static int aftercmp(int icon,char * p)
{
 return(cstrcmp(iconaddr(whandle[AFTER],icon),p));
}


static void settimeicon(void)
{
 char string[128];
 char * p;
 int  handle;

 handle=whandle[AFTER];

 writets(string,"%z12:%mi%am%0%W3 ,%DY%0%MO%0%ce%yr",&sxtimex);

 p=string;
 if(aftercmp(2,p))  writeicon(handle,2,p);
 p+=strlen(p)+1;
 if(aftercmp(7,p))  writeicon(handle,7,p);
 p+=strlen(p)+1;
 if(aftercmp(11,p)) writeicon(handle,11,p);
 p+=strlen(p)+1;
 if(aftercmp(14,p)) writeicon(handle,14,p);


 selectst(handle,15,xrepeat);
 writeiconf(handle,18,"%d",xevery);
 selectst(handle,20,xperiod==RMINUTE);
 selectst(handle,21,xperiod==RHOUR); 
 selectst(handle,22,xperiod==RDAY);
 selectst(handle,23,xperiod==RWEEK);
 selectst(handle,24,xperiod==RMONTH);

 selectst(handle,25,xsunday);
 selectst(handle,26,xmonday);
 selectst(handle,27,xtuesday);
 selectst(handle,28,xwednesday);
 selectst(handle,29,xthursday);
 selectst(handle,30,xfriday);
 selectst(handle,31,xsaturday);
}



static void changeevery(int inc)
{
 xevery+=inc?(1):(-1);
 writeiconf(whandle[AFTER],18,"%d",xevery);
}


int setupafter(setafterfn setafterx,int sxmenuvalid)
{
 int        handle;
 int        ns;
 int        k;
 schedule * sxp;

 setafterf=setafterx;

 handle=createwindow(AFTER);

 if(sxmenuvalid)
 {
  sxp=sxptr(sxmenu);
  if(sxp)
  {
   ns=schedselected(sxp,&k);
   if(ns) 
   {
    sxtimex=sxp->line[k].nextattempt;

    xrepeat=sxp->line[k].repeat;
    xevery=sxp->line[k].every;
    xperiod=sxp->line[k].period;

    xsunday=sxp->line[k].sunday;
    xmonday=sxp->line[k].monday;
    xtuesday=sxp->line[k].tuesday;
    xwednesday=sxp->line[k].wednesday;
    xthursday=sxp->line[k].thursday;
    xfriday=sxp->line[k].friday;
    xsaturday=sxp->line[k].saturday;
   }
  }
 }
 else 
 {
  getcurtime(&sxtimex);
  xrepeat=0;
  xperiod=0;
  xevery=1;
  xsunday=xmonday=xtuesday=xwednesday=xthursday=xfriday=xsaturday=1;
 }

 settimeicon();

 return(handle);
}


static void changehours(int inc)
{
 addtimex(&sxtimex,60*6000,inc);
 settimeicon();
}

static void changeminutes(int inc)
{
 addtimex(&sxtimex,6000,inc);
 settimeicon();
}

static void changeday(int inc)
{
 addtimex(&sxtimex,24*60*6000,inc);
 settimeicon();
}

static void changemonth(int inc)
{
 int yr;
 int mo;
 int dy;
 int days;
 int delta;

 getyearandmonth(&sxtimex,&yr,&mo,&dy);

 if(inc)
 {
  days=monthdays(mo,yr);
  delta=days-dy;
  if(++mo>12)
  {
   mo=1;
   yr++;
  }
  days=monthdays(mo,yr);
  if(dy>days) dy=days;
  delta+=dy;
 }
 else
 {
  delta=dy;
  if(--mo<1)
  {
   mo=12;
   if(--yr<0) yr=0;
  }
  days=monthdays(mo,yr);
  if(days<dy) dy=days;
  delta+=days-dy;
 }

 addtimex(&sxtimex,delta*24*60*6000,inc);

 settimeicon();
}


static void changeyear(int inc)
{
 int          yr;
 int          mo;
 int          dy;
 unsigned int delta;

 getyearandmonth(&sxtimex,&yr,&mo,&dy);

 if(inc)
 {
  delta=365;
  if((yr % 4)==0 && yr && mo<=2 && dy<29) delta++;
  yr++;
  if((yr % 4)==0 && yr && mo>2) delta++;
 }
 else
 if(yr)
 {
  delta=365;
  if((yr % 4)==0 && yr && mo>2) delta++;
  yr--;
  if((yr % 4)==0 && yr && mo<=2 && dy<29) delta++;
 }
 else return; /* -> */

 addtimex(&sxtimex,delta*24*60*6000,inc);

 settimeicon();
}



static void setaftersub(int all)
{
 int        i;
 schedule * sxp;

 sxp=sxptr(sxmenu);
 if(sxp)
 {
  for(i=0;i<sxp->entries;i++)
  {
   if(sxp->line[i].selected || all)
   {
    sxp->line[i].sent=0;
    sxp->line[i].after=1;
    sxp->line[i].hold=0;
    sxp->line[i].attempts=0;
    getcurtime(&sxp->line[i].lastattempt);
    sxp->line[i].nextattempt=sxtimex;

    sxp->line[i].every=xevery;
    sxp->line[i].period=xperiod;
    sxp->line[i].repeat=xrepeat;
    sxp->line[i].sunday=xsunday;
    sxp->line[i].monday=xmonday;
    sxp->line[i].tuesday=xtuesday;
    sxp->line[i].wednesday=xwednesday;
    sxp->line[i].thursday=xthursday;
    sxp->line[i].friday=xfriday;
    sxp->line[i].saturday=xsaturday;

    refreshlineentry(sxp,i);
    modschedule=1;
   }
  }
 }
 refreshviewline(sxmenu);
}


void setafter(void)
{
 setaftersub(0);
}



void setaftertime(int sx,arctime * sxtimex,int i)
{
 schedule * sxp;

 sxmenu=sx;
 sxp=sxptr(sx);
 if(sxp && i<sxp->entries)
 {
  sxp->line[i].after=1;
  sxp->line[i].hold=0;
  sxp->line[i].nextattempt=*sxtimex;
  refreshlineentry(sxp,i);
  modschedule=1;
 }

 refreshviewline(sx);
}


void aftericon(void)
{
 int adjust;
 int handle;

 adjust=(buttons==1);
 handle=whandle[AFTER];

 switch(icon)
 {
  case  0:
  case  1:
          changehours(adjust?icon==1:icon==0);
          break;

  case  3:
  case  4:
          changeminutes(adjust?icon==4:icon==3);
          break;

  case  6:
  case  8:
          changeday(adjust?icon==6:icon==8);
          break;

  case  9:
  case 10:
          changemonth(adjust?icon==9:icon==10);
          break;

  case 12:
  case 13:
          changeyear(adjust?icon==12:icon==13);
          break;

  case  5:        /* OK */
          if(setafterf) setafterf();
          if(!adjust) zapmenu();
          break;

  case 15:
          selectst(handle,15,xrepeat^=1);
          break;


  case 17:
  case 19:
          changeevery(adjust?icon==17:icon==19);
          break;


  case 20:
  case 21:
  case 22:
  case 23:
  case 24:
          deselect(handle,20+xperiod);
          xperiod=icon-20;
          select(handle,20+xperiod);
          break;

 case 25:
         selectst(handle,25,xsunday^=1);
         break;

 case 26:
         selectst(handle,26,xmonday^=1);
         break;

 case 27:
         selectst(handle,27,xtuesday^=1);
         break;

 case 28:
         selectst(handle,28,xwednesday^=1);
         break;

 case 29:
         selectst(handle,29,xthursday^=1);
         break;

 case 30:
         selectst(handle,30,xfriday^=1);
         break;

 case 31:
         selectst(handle,31,xsaturday^=1);
         break;
 }
}

