/* program to download ftp or http-files */

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <string.h>
#include <clib/diskfont_protos.h>

#include"tcpdl.h"

static struct Screen         *Scr = NULL;
static APTR                   VisualInfo = NULL;
static struct Window         *Wnd = NULL;
static UWORD                  Left = 127;
static UWORD                  Top = 155;
static UWORD                  Width = 521;
static UWORD                  Height = (14+9*(NUMBERPROCESSES+1));
static UBYTE                 *Wdt = (UBYTE *) VERSIONSTRING ;
struct TextAttr              Font;

struct MM *mmpoint;

#define debug_main(x) ;

void 
main(int argc,char *argv[])
{
struct Library *SocketBase;
int task,i,n;
ULONG crc;
struct namedata *urldata;
struct namedata *urldatatemp;
struct TextFont *fontpointer;
ULONG temptime;
ULONG dummy;
BOOL quitprg=FALSE;

   printf("%s\n", VERSIONSTRING );
   
   mmpoint = AllocMem( sizeof(struct MM), MEMF_CLEAR|MEMF_PUBLIC );
   if( mmpoint==0 )
   {
      printf( "Couldn't allocmem %d bytes\n", sizeof( struct MM) );
      exit(0);
   }
   else
      printf( "%d bytes allocated\n", sizeof(struct MM) );
   
   CurrentTime( &temptime, &dummy);
   mmpoint->starttime=temptime;
   
   for( task=0;task<NUMBERPROCESSES;task++)
   {
      sprintf( mmpoint->point[task].information1, "%s", "<none>     " );
      mmpoint->point[task].finalsize=-1;
      mmpoint->point[task].currentsize=-1;
      mmpoint->point[task].timeout=10;
   }
   
   for( i=0; i<256; i++ )
   {
      crc = i;
      for( n=1; n<9; n++)
      {
         if( crc & 1 )
            crc = (crc >> 1) ^ 0xedb88320;
         else
            crc = crc >> 1;
      }
      mmpoint->crctab[i] = crc;
   }
   
   i=1;
   while( i<argc )
   {
      if( Strnicmp( argv[i], "NOMODIFY", -1 )==0 )
         mmpoint->nomodify=TRUE;
      
      printf("DEBUG: arg%d: \"%s\"\n", i, argv[i]);
      i++;
   }
   
   if( SetupScreen()!=0 )
   {
      if( mmpoint!=0 )
         FreeMem( mmpoint, sizeof( struct MM ) );
      printf("Unable to open Workbench\n");
      return;
   }
   
   Font.ta_Name = (STRPTR)"xen.font";
   Font.ta_YSize = 8;
   Font.ta_Style = 0;
   Font.ta_Flags = 0;
   
   fontpointer = OpenDiskFont( &Font );
   if( fontpointer==0 )
      printf( "xen.font not found.\n");
   else
      printf( "xen.font found.\n");
    
   if( OpenWnd()!=0 )
   {
      if( mmpoint!=0 )
         FreeMem( mmpoint, sizeof( struct MM ) );
      printf("Unable to open Window\n");
      CloseDownScreen();
      CloseFont( fontpointer );
      return;
   }
   
   readconfig();
   
   createpath( "tcpdldir:data/temp/" );
   
   readurlfile( "tcpdldir:urllist" );
   
   SocketBase = (struct Library *) OpenLibrary( "bsdsocket.library", (2L) );
   
   if( SocketBase!=0 )
   {
      SetTaskPri( FindTask(0), 2 );
      debug_main( printf("Starting subtaskes\n"); )
      starttask( );
      debug_main( printf("subtaskes started\n"); )
      
      while( TRUE )
      {
         for( task=0;task<NUMBERPROCESSES;task++ )
         {
            InfoToProcess( task );
            Delay(2);
         }
            
         if( SetSignal( 0L, SIGBREAKF_CTRL_C )&SIGBREAKF_CTRL_C )
         {
            mmpoint->ctrlcflag=TRUE;
            break;
         }
         
         if( mmpoint->ctrlcflag==TRUE )
            break;
         
         if( mmpoint->ALLDONE==TRUE )
         {
            quitprg=TRUE;
            for( task=0;task<NUMBERPROCESSES;task++)
            {
               if( mmpoint->point[task].busy==TRUE )
               {
                  quitprg=FALSE;
                  mmpoint->ALLDONE=FALSE;
                  break;
               }
            }
         }
         
         if( quitprg==TRUE )
            break;
      }
      
      debug_main( printf("Work done\n"); );
      CloseLibrary( SocketBase );
   }
   else
      printf( "Error:Can't open bsdsocket.library!\n");
   
   for( task=0;task<NUMBERPROCESSES;task++)
      mmpoint->point[task].kill=TRUE;
   
   if( mmpoint->ctrlcflag==TRUE )
      printf( "***User break\n");
   
   for( task=0;task<NUMBERPROCESSES;task++)
   {
      while( mmpoint->point[task].taskid!=0 )
         Delay(10);
   }
   
   mmpoint->task_safe_kill=TRUE;
   while( mmpoint->task_safe_taskid!=0 )
      Delay(10);
   
   mmpoint->task_update_window_kill=TRUE;
   while( mmpoint->task_update_window_taskid!=0 )
      Delay(10);
   
   debug_main( printf("Tasks stopped\n"); )
   
   CloseWnd();
   CloseDownScreen();
   
   CloseFont( fontpointer );
   
   printf("Freeing memory. Hold on...\n");
   
   urldata=mmpoint->firsturldata;
   while( urldata!=0 )
   {
      if( urldata->urlnamelength!=0 )
         FreeMem( urldata->urlname,     urldata->urlnamelength );
      
      if( urldata->typenamelength!=0 )
         FreeMem( urldata->typename,    urldata->typenamelength );
      
      if( urldata->hostnamelength!=0 )
         FreeMem( urldata->hostname,    urldata->hostnamelength );
      
      if( urldata->pathnamelength!=0 )
         FreeMem( urldata->pathname,    urldata->pathnamelength );
      
      if( urldata->urlfilenamelength!=0 )
         FreeMem( urldata->urlfilename, urldata->urlfilenamelength );
      
      urldatatemp=urldata->next;
      FreeMem( urldata, sizeof( struct namedata ) );
      urldata=urldatatemp;
   }
   
   if( mmpoint!=0 )
      FreeMem( mmpoint, sizeof( struct MM ) );
   
   printf("Ok. Exiting!\n");
   
   return;
}

int __saveds
OpenWnd( void )
{
    UWORD offy = Scr->WBorTop + Scr->RastPort.TxHeight + 1;
    
    if ( ! ( Wnd = OpenWindowTags( NULL,
                    WA_Left,          (Scr->Width-Width)/2,
                    WA_Top,           (Scr->Height-(Height+offy))/2,
                    WA_Width,         Width,
                    WA_Height,        Height + offy,
                    WA_IDCMP,         NULL,
                    WA_Flags,         WFLG_DRAGBAR|WFLG_DEPTHGADGET,
                    WA_Title,         Wdt,
                    WA_ScreenTitle,   VERSIONSTRING,
                    TAG_DONE )))
        return( 4L );

    GT_RefreshWindow( Wnd, NULL );

    Render();

    return( 0L );
}

void __saveds
CloseWnd( void )
{
    if ( Wnd        ) {
        CloseWindow( Wnd );
        Wnd = NULL;
    }
}

int __saveds
SetupScreen( void )
{
    if ( ! ( Scr = LockPubScreen((UBYTE * )"Workbench" )))
        return( 1L );

    if ( ! ( VisualInfo = GetVisualInfo( Scr, TAG_DONE )))
        return( 2L );

    return( 0L );
}

void __saveds
CloseDownScreen( void )
{
    if ( VisualInfo ) {
        FreeVisualInfo( VisualInfo );
        VisualInfo = NULL;
    }

    if ( Scr        ) {
        UnlockPubScreen( NULL, Scr );
        Scr = NULL;
    }
}

struct IntuiText  ITextH[] = {
    1, 0, JAM2,2,  2, NULL, NULL, NULL };

struct IntuiText  ITextT[] = {
    1, 0, JAM2,2,  2, NULL, NULL, NULL };

void __saveds
Render( void )
{
char text[240];
char textH[120];
char fsizetext[20];
char csizetext[20];
char timetext[20];
char cpstext[20];
ULONG time;
ULONG minute;
ULONG second;
ULONG dummy;

ULONG starttime;
LONG  currentsize;
LONG  currentsizecps;
LONG  finalsize;
ULONG starttimecps;
ULONG totalbytes;
ULONG cps;
int i;

UWORD offx, offy;

    offx = Wnd->BorderLeft;
    offy = Wnd->BorderTop;
    
    ITextH->IText=(UBYTE*)textH;
    Forbid();
    sprintf( textH, "Status        Time    CPS  CSize  FSize  Request (DONE:%d TOTAL:%d)       ", mmpoint->numberurldatadone, mmpoint->numberurldata );
    Permit();
    
    ITextH->ITextFont=&Font;
    PrintIText( Wnd->RPort, ITextH, offx, offy );
    
    ITextT->ITextFont=&Font;
    ITextT->IText=(UBYTE*)text;
    
    Forbid();
    CurrentTime( &time, &dummy);
    Permit();
    
    for(i=0;i<NUMBERPROCESSES;i++)
    {
       Forbid();
       
       if( mmpoint->point[i].taskid!=0 )
       {
          if( (mmpoint->ctrlcflag==TRUE) )
             Signal( mmpoint->point[i].taskid, SIGBREAKF_CTRL_C );
          
          if( mmpoint->point[i].at_work!=0 )
          {
             mmpoint->point[i].at_work=0;
             mmpoint->point[i].at_work_time=time;
          }
          else
          if( (time-mmpoint->point[i].at_work_time)>mmpoint->point[i].timeout )
             Signal( mmpoint->point[i].taskid, SIGBREAKF_CTRL_C );
       }
          
       
       starttime=mmpoint->point[i].starttime;
       currentsize=mmpoint->point[i].currentsize;
       currentsizecps=mmpoint->point[i].currentsizecps;
       finalsize=mmpoint->point[i].finalsize;
       starttimecps=mmpoint->point[i].starttimecps;
       
       Permit();
       
       if( (starttime!=0) & (time>starttime) )
       {
          minute=(time-starttime)/60;
          second=(time-starttime)-minute*60;
          sprintf( timetext, "%2d:%02d", minute, second );
       }
       else
          sprintf( timetext, "-" );
       
       if( currentsize==-1 )
          sprintf( csizetext, "-" );
       else
       {
          if( currentsize<1048576 )
             sprintf( csizetext, "%dk", currentsize/1024 );
          else
             sprintf( csizetext, "%dM", currentsize/1048576 );
       }
       
       if( finalsize==-1 )
          sprintf( fsizetext, "-" );
       else
       {
          if( finalsize<1048576 )
             sprintf( fsizetext, "%dk", finalsize/1024 );
          else
             sprintf( fsizetext, "%dM", finalsize/1048576 );
       }
       
       if( (starttimecps!=0) & (starttimecps<time) )
          sprintf( cpstext, "%d", currentsizecps/(time-starttimecps) );
       else
          sprintf( cpstext, "-" );
       
       sprintf( text, "%s  %5s  %5s  %5s  %5s  %s", mmpoint->point[i].information1, timetext, cpstext, csizetext, fsizetext, mmpoint->point[i].information2 );
       PrintIText( Wnd->RPort, ITextT, offx, offy+i*9+9 );
    }
    

    minute=(time-mmpoint->starttime)/60;
    second=(time-mmpoint->starttime)-minute*60;
    
    if( time<mmpoint->starttime )
    {
       minute=0; second=0;
    }
    
    Forbid();
    totalbytes=mmpoint->totalbytes;
    if( ((time-mmpoint->starttime)!=0) & (time>mmpoint->starttime) )
       cps=totalbytes/(time-mmpoint->starttime);
    else
       cps=0;
    Permit();

    sprintf( text, "Total time: %d:%02d, Total bytes: %dk, Average cps:%d          ", minute, second, totalbytes/1024, cps );
    
    PrintIText( Wnd->RPort, ITextT, offx, offy+(NUMBERPROCESSES+1)*9 );
    return;
}

