/*->c.viewtx    */

/* Spark!   (c) D. J. Pilling,     April 1989                         */
/*                   Filing System  Interface                         */


#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.sprite"
#include "h.bbc"
#include "h.flex"
#include "h.swis"



#include "h.Drawlevel0"

#include "h.etc"

#include "h.def"
#include "h.wos"
#include "h.timex"
#include "h.strdef"
#include "h.mym"
#include "h.dir"
#include "h.batch"
#include "h.sched"
#include "h.fsx"
#include "h.pic"
#include "h.vx"
#include "h.trans"
#include "h.tiff"
#include "h.file"
#include "h.err"
#include "h.replay"
#include "h.main"
#include "h.state"
#include "h.newfax"


#include "h.view"



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


static char * typetosprite(int type,char * name)
{
 static char sp[16];
 char        temp[FSMAXLEAF];
 os_error  * errpoi;


 if(type==CODE) strcpy(sp,"Sfile_xxx");
 else
 if(type==DIR)  sprintf(sp,"SDirectory");
 else
 if(type==APP)
 {
  strcpy(temp,name);
  temp[12]=0;
  strcpy(sp,temp);
  errpoi=wimp_spriteop(24,sp);
  if(!errpoi)
   sprintf(sp,"S%s",temp);
  else
   strcpy(sp,"SApplication");
 }
 else
 {
  sprintf(sp,"file_%03x",type);
  errpoi=wimp_spriteop(24,sp);
  if(!errpoi)
   sprintf(sp,"Sfile_%03x",type);
  else
   strcpy(sp,"Sfile_xxx");
 }
 return(sp);
}


static char * tinysp(int type,char * name)
{
 static char sp[16];
 char        temp[FSMAXLEAF];
 os_error  * errpoi;

 if(type==CODE) strcpy(sp,"Ssmall_xxx");
 else
 if(type==DIR)  sprintf(sp,"Ssmall_dir");
 else
 if(type==APP)
 {
  strcpy(temp,name);
  temp[12]=0;
  strcpy(sp,"sm");
  strcat(sp,temp);
  sp[12]=0;
  errpoi=wimp_spriteop(24,sp);
  if(!errpoi)
   sprintf(sp,"Ssm%s",temp);
  else
   strcpy(sp,"Ssmall_app");
 }
 else
 {
  sprintf(sp,"small_%03x",type);
  errpoi=wimp_spriteop(24,sp);
  if(!errpoi)
   sprintf(sp,"Ssmall_%03x",type);
  else
   strcpy(sp,"Ssmall_xxx");
 }
 return(sp);
}


void setsprites(int posn)
{
 int    type;
 char * name;

 type=vtable[view][posn].stat.type;
 if(type==ARCHIVE && vtable[view][posn].tsum.maxwidth==1)
 {
  if(vtable[view][posn].name[0]=='!') type=APP;
  else                                type=DIR;
 }

 name=vtable[view][posn].name;

 strcpy(vtable[view][posn].typs,typetosprite(type,name));
 strcpy(vtable[view][posn].tiny,tinysp(type,name));
}


void setspritesr(int posn)
{
 setsprites(posn);
 seti(viewhandle[view],vtable[view][posn].icon,0,0);
}


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

/* we just inserted another header/file in the current file table */
/* posn      the location in the ftable to put new entry          */


void insertentry(int posn,ficon * fi,int ow)
{
 int i;

 trashicons(view);  /* there's a catch */
                    /* fi will overwrite any icon numbers - prob. for ow */

 if(!ow)
 {
/*  if(vobject[view]>=posn) vobject[view]++; */
  vnofiles[view]++;
  setnofiles(view,vnofiles[view]);
  for(i=vnofiles[view]-2;i>=posn;i--) vtable[view][i+1]=vtable[view][i];
 }

 memset(&vtable[view][posn],0,sizeof(ficon));
 vtable[view][posn]=*fi;
 vtable[view][posn].selected=0;
 vtable[view][posn].icon=-1;

 setsprites(posn);
 refreshallviews();
 batchcheck();
}


/* delete an entry from the table */

static void deleteentrylo(int posn,int del)
{
 int i;
 char lname[64];

 delschedulehi(vtable[view][posn].schedule);

 sprintf(lname,"%s.%s",xvname(view),vtable[view][posn].name);

 if(del) remove(lname);

 newfaxdelete(posn);

/*
 if(vobject[view]==posn) vobject[view]=-1;
 else
 if(vobject[view]>posn)  vobject[view]--;
 */

 for(i=posn;i<vnofiles[view]-1;i++) vtable[view][i]=vtable[view][i+1];

 vnofiles[view]--;
 batchcheck();
}



void deleteentry(int posn,int del)
{
 trashicons(view);
 deleteentrylo(posn,del);
 setnofiles(view,vnofiles[view]);
 refreshallviews();
 batchmodded=1;
 saveconfig();
}



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

void writetypest(char * string,int posn)
{
 os_regset rx;
 int i,type;

 type=vtable[view][posn].stat.type;

 if(type==CODE) strcpy(string,transtoken("Code"));
 else
 {
  rx.r[0]=18;
  rx.r[2]=type;
  os_swix(OS_FSControl,&rx);
  string[0]=rx.r[2];
  string[1]=rx.r[2]>>8;
  string[2]=rx.r[2]>>16;
  string[3]=rx.r[2]>>24;
  string[4]=rx.r[3];
  string[5]=rx.r[3]>>8;
  string[6]=rx.r[3]>>16;
  string[7]=rx.r[3]>>24;
  for(i=0;i<8;i++) if(string[i]<=32) break;
  string[i]=0;
 }
}


void writetype(int window,int icon,int posn)
{
 char string[32];
 writetypest(string,posn);
 writeiconf(window,icon,"%s (%x)",string,vtable[view][posn].stat.type);
}



void writens(char * string,int val)
{
 os_regset rx;

 rx.r[0]=val;
 rx.r[1]=(int)string;
 rx.r[2]=12;

 os_swix(OS_ConvertFixedFileSize,&rx);
}



/* contents of text field */

/*  0..12 type        */
/* 12..16 size 1234K  */
/* 17 space           */
/* 18..23 status      */
/* 24 space           */
/* 25..43 open time   */
/* 44 space           */
/* 45..51 protocol    */
/* 52 space           */
/* 53..61 txtime      */


void writetextdata(int posn)
{
 arctime atx;
 char *  text=vtable[view][posn].text;
 int     i;

 for(i=0;i<64;i++) text[i]=0;

 writens(text+12,vtable[view][posn].stat.length);
 text[16]=text[17];
 text[17]=0;

 writetypest(text,posn);

 if(view==TXBFILE) summaryschedule(vtable[view][posn].schedule,text+18);
 else
 {
  if(vtable[view][posn].new) strcpy(text+18,transtoken("New"));
  else                       strcpy(text+18,transtoken("Rcvd"));
 }

 atx.lo=vtable[view][posn].stat.exec;
 atx.hi=vtable[view][posn].stat.load & 0xFF;

 writetimedate(text+25,&atx);

 vtable[view][posn].text[63]=0;
}


int setupinfo(void)
{
 int handle;
 int i;
 int n;

 closedownt(FINFO);
 closedownt(VINFO);
 closedownt(DINFO);

 n=selected(&i);

 if(vtable[view][i].stat.type==TIFF)
 {
  handle=createwindow(FINFO);
  if(handle)
  {
   writeiconf(handle,8,"%d",vtable[view][i].tsum.npages);

   writeiconf(handle,9,"%d x %d %s",vtable[view][i].tsum.xres,
               vtable[view][i].tsum.yres,transtoken("VIEW06"));

   writeiconf(handle,15,"%d x %d %s",vtable[view][i].tsum.maxwidth,
                vtable[view][i].tsum.maxlines,transtoken("VIEW05"));

   writeicon(handle,10,transtoken(view==TXBFILE?"RXID":"TXID"));
   writeicon(handle,11,vtable[view][i].ident);
  }
 }
 else
 if(vtable[view][i].stat.type==ASND)
 {
  handle=createwindow(VINFO);
  if(handle)
  {
   writeiconf(handle,8,"%d",vtable[view][i].tsum.npages);
   writeiconf(handle,9,"%d",vtable[view][i].tsum.xres);
   writeicon(handle,14,
         voicecompressionname[voiceindex(vtable[view][i].tsum.maxwidth)]);
  }
 }
 else    /* the rest */
 {
  handle=createwindow(DINFO);
  if(handle)
  {
   writeicon(handle,5,vtable[view][i].typs+1);
  }
 }

 if(handle)
 {
  writeicon(handle,0,vtable[view][i].name);
  writeiconf(handle,1,"%d",(int)vtable[view][i].stat.length);
  writetype(handle,2,i);
  writefiletime(iconaddr(handle,3),&vtable[view][i].stat);
 }

 return(handle);
}



static int coherent(void)
{
 int i;
 int type;

 type=-1;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected)
  {
   if(type==-1) type=vtable[view][i].stat.type;
   else
   if(type!=vtable[view][i].stat.type)
   {
    type=-1;
    break;
   }
  }
 }
 return(type);
}




static int menuview;


static void setpopview(void)
{
 int  n;
 char string[256];
 int  i;
 int  posn;
 int  type;

 view=menuview;

 for(i=0;i<7;i++) untick(disp_menu,i);
 tick(disp_menu,viewdisp[view]);
 tick(disp_menu,viewsort[view]+3);

 n=getinfo(string,&posn);


 if(n) type=coherent();
 else  type=-1;

 strcpy(menuaddr(view_menu,1),string);


 for(i=strlen(string);i<18;i++)
 {
  *(menuaddr(view_menu,1)+i)=32;
 }

 unshadest(view_menu,1,n);

 unshadest(action_menu,0,n==1);   /* info */
 unshadest(action_menu,1,n);      /* del  */
 unshadest(action_menu,2,n==1);   /* rename */
 unshadest(action_menu,3,n>1 && type==TIFF); /* Merge */
 unshadest(action_menu,4,n   && type==TIFF); /* Print */
 unshadest(action_menu,5,n   && (type==TIFF || type==ASND));  /* View */
 unshadest(action_menu,6,n   && view==TXBFILE); /* Sched */
 unshadest(action_menu,7,n   && view==TXBFILE); /* Add entry */
 unshadest(action_menu,8,n   && view==TXBFILE); /* Entry menu */

 writemenu(action_menu,5,(type==ASND)?"Play...":"View...");

 if(n && view==TXBFILE)
 {
  setpopbatchsched(vtable[view][posn].schedule);
 }

 if(n>=1) strcpy(menuaddr(rename_menu,0),vtable[view][posn].name);
}



#define SPLITS 4

static int splits[SPLITS]=
{
 0,
 12,
 18,
 25,
};



static void viewredrawsub(wimp_redrawstr * redrawstr,int more)
{
 int oy;
 int ox;
 int ylo;
 int yhi;
 int n;
 int y;
 int x;
 int i;

 wimpfontstart();

 while(more)
 {
  if(viewdisp[view]==2)
  {
   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 */


   for(n=0;n<vnofiles[view];n++)
   {
    x=vtable[view][n].x+WIDTH;
    y=vtable[view][n].y+HEIGHT-VMARGIN;


    if(y<=(ylo+HEIGHT) && y>=yhi)
    {
     for(i=0;i<SPLITS;i++)
     {
      stringat(ox+x+splits[i]*wimpavfontwidth,oy+y,
           vtable[view][n].text+splits[i],(1<<8)|7,HEIGHT-2*VMARGIN);
     }
    }
   } 
  }
  wimp_get_rectangle(redrawstr,&more);
 }

 wimpfontend();
}




void viewredraw(void)
{
 wimp_redrawstr redrawstr;
 int            more;

 redrawstr.w=ewindow;

 wimp_redraw_wind(&redrawstr,&more);
 viewredrawsub(&redrawstr,more);
}



void viewupdatetexticon(int posn)
{
 wimp_redrawstr r;
 int            handle;

 writetextdata(posn);
 if(viewdisp[view]==2)
 {
  handle=viewhandle[view];
  if(handle)
  {
   getw(handle);
   r.box.x0=vtable[view][posn].x+WIDTH+bx;
   r.box.y0=vtable[view][posn].y+VMARGIN+by;
   r.box.x1=vtable[view][posn].x+WIDTH+TEXTW+bx;
   r.box.y1=vtable[view][posn].y+HEIGHT-VMARGIN+by;
   r.w=-1;
   wimp_force_redraw(&r);
  }
 }
}


static void viewremove(int del)
{
 int i;

 trashicons(view);

 for(i=0;i<vnofiles[view];i++)
   if(vtable[view][i].selected) deleteentrylo(i--,del);

 setnofiles(view,vnofiles[view]);
 refreshallviews();
}


void batchviewvx(int vn,int i)
{
 if(vtable[vn][i].new)
 {
  vtable[vn][i].new=0;
  viewupdatetexticon(i);
  batchmodded=1;
 }
 if(vtable[vn][i].stat.type==TIFF) report(newvx(vn,i));
 else
 if(vtable[vn][i].stat.type==ASND) repvn(vn,i);
}

static void viewvx(void)
{
 int  i;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected)
  {
   batchviewvx(view,i);
  }
 }
}

static void viewsched(void)
{
 int i;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected && vtable[view][i].schedule)
  {
   openschedule(view,i,vtable[view][i].schedule);
  }
 }
}



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

static void viewupdatesched(void)
{
 if(!onlinestate()) setuptarget();
 saveconfig();
}


static void viewstrip(char * dest,char * src)
{
 while((*dest++=*src++)>=32);
 *(dest-1)=0;
}


static void viewentry(int m3,int m4,int m5)
{
 int i;
 int hit;

 hit=0;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected && vtable[view][i].schedule)
  {
   scheddecodebatch(m3,m4,m5,vtable[view][i].schedule);
   hit=1;
  }
 }

 if(hit) viewupdatesched();
}


static void viewaddentry(int m3)
{
 int i;
 int hit;

 hit=0;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected && vtable[view][i].schedule)
  {
   scheddecodebatchdial(m3,vtable[view][i].schedule);
   hit=1;
  }
 }

 if(hit) viewupdatesched();
}



void viewafter(void)
{
 int i;
 int hit;

 hit=0;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected && vtable[view][i].schedule)
  {
   scheddecodebatchafter(vtable[view][i].schedule);
   hit=1;
  }
 }

 if(hit) viewupdatesched();
}



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



int findviewsn(int sn)
{
 int i;

 for(i=0;i<vnofiles[TXBFILE];i++)
 {
  if(vtable[TXBFILE][i].schedule==sn) return(i);
 }

 return(-1);
}


/* passed batch index, and new leaf name */
/* return new batch index */

int viewrenamelo(int src,char * leaf)
{
 char       olname[FSMAXLEAF];
 char       nlname[FSMAXLEAF];
 char       newleaf[FSMAXLEAF];
 os_error * ep;
 int        dest;
 ficon      ticon;

 viewstrip(newleaf,leaf);

 sprintf(olname,"%s.%s",xvname(view),vtable[view][src].name);
 sprintf(nlname,"\"%s.%s\"",xvname(view),newleaf);

 dest=src;

 ep=fs_rename(olname,nlname);
 if(!ep)
 {
  for(dest=0;dest<vnofiles[view];dest++)
  {
   if(cstrcmp(vtable[view][dest].name,newleaf)>=0) break;
  }

  strcpy(vtable[view][src].name,newleaf);

  ticon=vtable[view][src];
 
  if(dest<src)
  {             /* move dest to src-1 up by one */
   memmove(&vtable[view][dest+1],&vtable[view][dest],sizeof(ficon)*(src-dest));
  }
  else
  if(dest>src)
  {            /* move src+1 to dest down by one */
   dest--;
   memmove(&vtable[view][src],&vtable[view][src+1],sizeof(ficon)*(dest-src));
  }

  vtable[view][dest]=ticon;

  refreshview(1);
 }
 else report(ep);

 return(dest);
}



static void viewrename(void)
{
 int        i;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected)
  {
   viewrenamelo(i,menuaddr(rename_menu,0));
   break;
  }
 }
}


static void viewmerge(char * xnewname)
{
 os_error * err;
 int        i;
 char       name[FSMAXLEAF];
 char       merge[FSMAXLEAF];
 int        fh;
 int        sh;
 framestr   sx;
 int        ptot;
 int        pn;
 int        n;
 tiffsum    tsum;
 char     * buff;
 int        bn;
 char       newname[FSMAXLEAF];

 viewstrip(newname,xnewname);

 err=NULL;

 tsum.maxwidth=0;
 tsum.maxlines=0;
 tsum.xres=0;
 tsum.yres=0;

 n=ptot=0;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected)
  {
   n++;
   ptot+=vtable[view][i].tsum.npages;

   if(!cstrcmp(vtable[view][i].name,newname))
   {
    err=&err_batclash;
    break;
   }

   tsum.maxwidth=MAX(tsum.maxwidth,vtable[view][i].tsum.maxwidth);
   tsum.maxlines=MAX(tsum.maxlines,vtable[view][i].tsum.maxlines);
   tsum.xres=MAX(tsum.xres,vtable[view][i].tsum.xres);
   tsum.yres=MAX(tsum.yres,vtable[view][i].tsum.yres);
  }
 }

 tsum.npages=ptot;


 if(n>1 && !err)
 {
  sprintf(merge,"%s.%s",xvname(view),newname);
  err=fs_open(merge,'w',&fh);
  if(!err)
  {
   tiff_hdr(fh);
   pn=1;

   for(i=0;i<vnofiles[view];i++)
   {
    if(vtable[view][i].selected)
    {
     sprintf(name,"%s.%s",xvname(view),vtable[view][i].name);
     err=fs_open(name,'r',&sh);

     if(!err)
     {
      err=tiff_readhdr(sh);
   
      while(!err)
      {
       err=tiff_readframe(sh,&sx);
       if(err) break;
       fs_seek(sh,sx.strip);

       sx.pn=pn++;
       sx.tot=ptot;

       faxifdwr(fh,&sx);

       /* copy length from sh to fh */

       err=flex_alloce((flex_ptr)&buff,sx.length);
       if(err) break;
 
       fs_read(sh,buff,sx.length);
       fs_write(fh,buff,sx.length);

       flex_free((flex_ptr)&buff);

       if(!sx.next) break;
       err=fs_seek(sh,sx.next);
       if(err) break;
      }
      err=fs_close(sh,err);
     }
     if(err) break;
    }
   }
   err=fs_close(fh,err);
   if(err) fs_delete(merge);
   else
   {
    setftype(merge,TIFF);

    if(view==TXBFILE) bn=addtotxbatch(TIFF,merge,1,0)-1;
    else              bn=addtorxbatch(TIFF,merge,1,0)-1;

    vtable[view][bn].tsum=tsum;
   }
  }
 }
 report(err);
}




static int viewfind(int view,char * name)
{
 int i;

 for(i=0;i<vnofiles[view];i++)
 {
  if(!cstrcmp(vtable[view][i].name,name)) return(i);
 }

 return(-1);
}







int viewmergeadd(int view,int newbn,char * p)
{
 os_error * err;
 char       name[FSMAXLEAF];
 char       merge[FSMAXLEAF];
 int        fh;
 int        sh;
 framestr   sx;
 int        ptot;
 int        pn;
 tiffsum    tsum;
 char     * buff;
 int        merbn;
 int        posn;


 err=NULL;

 merbn=viewfind(view,p);
 if(merbn>=0)
 {
  tsum.maxwidth=MAX(vtable[view][newbn].tsum.maxwidth,vtable[view][merbn].tsum.maxwidth);
  tsum.maxlines=MAX(vtable[view][newbn].tsum.maxlines,vtable[view][merbn].tsum.maxlines);
  tsum.xres=MAX(vtable[view][newbn].tsum.xres,vtable[view][merbn].tsum.xres);
  tsum.yres=MAX(vtable[view][newbn].tsum.yres,vtable[view][merbn].tsum.yres);

  pn=1;
  tsum.npages=ptot=
             vtable[view][newbn].tsum.npages+vtable[view][merbn].tsum.npages;

  sprintf(merge,"%s.%s",xvname(view),vtable[view][newbn].name);
  err=fs_open(merge,'u',&fh);
  if(!err)
  {
   err=tiff_readhdr(fh);
   
   while(!err)
   {
    fs_tell(fh,&posn);
    err=tiff_readframe(fh,&sx);
    if(err) break;
    fs_seek(fh,posn);

    sx.pn=pn++;
    sx.tot=ptot;

    faxifdwr(fh,&sx);

    if(!sx.next)
    {
     fs_tell(fh,&posn);
     fs_seek(fh,posn+sx.length);
     break;
    }

    err=fs_seek(fh,sx.next);
    if(err) break;
   }


   sprintf(name,"%s.%s",xvname(view),vtable[view][merbn].name);
   err=fs_open(name,'r',&sh);
   if(!err)
   {
    err=tiff_readhdr(sh);
   
    while(!err)
    {
     err=tiff_readframe(sh,&sx);
     if(err) break;
     fs_seek(sh,sx.strip);

     sx.pn=pn++;
     sx.tot=ptot;

     faxifdwr(fh,&sx);

     /* copy length from sh to fh */

     err=flex_alloce((flex_ptr)&buff,sx.length);
     if(err) break;
 
     fs_read(sh,buff,sx.length);
     fs_write(fh,buff,sx.length);

     flex_free((flex_ptr)&buff);

     if(!sx.next) break;
     err=fs_seek(sh,sx.next);
     if(err) break;
    }
    err=fs_close(sh,err);
   }
   err=fs_close(fh,err);

   if(!err)
   {
    vtable[view][newbn].tsum=tsum;
    stat(merge,&vtable[view][newbn].stat);
   }
  }
 }

 report(err);

 return(0);
}





static void viewprintselection(void)
{
 os_error * err;
 int        i;
 int        warn;
 char       name[256];

 err=NULL;

 getprintername(name);

 warn=!strcmp(name,"ArcFax");

 if(!warn || confirm(CONYN,"{VX00}")>0)
 {
  for(i=0;i<vnofiles[view];i++)
  {
   if(vtable[view][i].selected)
   {
    err=vxprintfax(view,i);
    if(err) break;
   }
  }
 }
 report(err);
}



static void decodeselection(int m2,int m3,int m4,int m5)
{
 switch(m2)
 {
  case 1:
         viewremove(1);          /* delete */
         break;

  case 2:                        /* rename */
         if(m3==0) viewrename();
         break;

  case 3:
         viewmerge(menuaddr(rename_menu,0));
         break;

  case 4:
         viewprintselection();
         break;

  case 5:
         viewvx();
         break;

  case 6:                        /* Schedule */
         viewsched();
         break;

  case 7:                        /* add entry */
         viewaddentry(m3);
         break;

  case 8:                        /* entry menu */
         viewentry(m3,m4,m5);
         break;

 default:
         return;
 }
 batchmodded=1;
}




void decodeview(int m1,int m2,int m3,int m4,int m5)
{
 view=menuview;

 switch(m1)
 {
  case 0:
         switch(m2)       /* display */
         {
          case 0:
          case 1:
          case 2:
                 viewdisp[view]=display=m2;
                 refreshview(1);
                 break;
          case 3:
          case 4:
          case 5:
          case 6:
                 viewsort[view]=sort=m2-3;
                 refreshview(0);
                 break;
          }
          break;


   case 1:                 /* selection */
          decodeselection(m2,m3,m4,m5);
          break;

   case 2:                 /* select all */
          selectall();
          break;

   case 3:                 /* clear selection */
          unselectall();
          break;

   case 4:                 /* open directory */
          opendir();
          break;
 }

 setpopview();
 m3=0;
}


void popview(void)
{
 menuview=view;
 selectone();
 setpopview();
 popmenu(view_menu);
}


