/* Copyright © 1995-1996 : David Atkinson */
/* V1.22 Ports.c */
/* Calgor */
#include <hold/extra.h>

#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

#include <exec/types.h>
#include <dos/dos.h> /* get BPTR define */
#include <graphics/view.h>
#include <graphics/gfx.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/console_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/graphics_protos.h>

extern void al_clean(void);

extern struct Library *IntuitionBase;
extern struct Library *ConsoleDevice;
extern struct GfxBase *GfxBase;
extern struct TextFont *font_ptr;
extern struct TextFont *cfontptr;
extern struct View ft_view;
extern struct View sec_view;
extern struct ViewPort ft_viewport;
extern struct ViewPort sec_viewport;
extern struct BitMap ft_bitmap;
extern struct BitMap sec_bitmap;
extern struct BitMap thd_bitmap;
extern struct Screen *my_screen;
extern struct ViewExtra *ft_vextra;
extern struct ViewExtra *sec_vextra;
extern struct ViewPortExtra *vpone_extra;
extern struct ViewPortExtra *vptwo_extra;
extern struct MonitorSpec *monspec;
extern struct MsgPort *aport;
extern struct IOStdReq ioreq;
extern struct Library *DiskfontBase;
extern struct Library *WorkbenchBase;
extern struct Window *my_window;

#ifdef TEST
extern SHORT Diagnostic;
#endif
extern UBYTE *keybufptr;             /* Keyboard buffer */
extern char *buffer;
extern char *display;
extern UWORD wb_version;

BPTR recordone;
BPTR recordtwo;

#ifdef TEST
void clear_log(void);
void write_log(TEXT *, SHORT);
#endif
void cleanup(void);
void alert(TEXT *);
void shutdown(void);
void clearkeybuf(void);

#ifdef TEST
void clear_log(void){
  recordone = open("Cal:CalLog",O_CREAT|O_TRUNC|O_RDWR);
  if(recordone>=0)
    close(recordone);
}
#endif

#ifdef TEST
void write_log(TEXT *message,SHORT leveld)
{
long bytes_read=0;

    if(leveld<=Diagnostic){
      recordtwo = open("Cal:CalLog",O_APPEND|O_RDWR);
      if(recordtwo>=0){
        bytes_read=write(recordtwo,message,strlen(message));
        close(recordtwo);
      }
    }
}
#endif

void clearkeybuf(void){
int loop;

    for(loop=0;loop<KEYBUFF;loop++)
      *(keybufptr+loop)= '\0';
}

void cleanup()
{
int loop;

/* Be careful not to use library routines that have failed to open */
  #ifdef TEST
    write_log("Cleanup Entered\n",PRIONE);
  #endif
  system("cpu datacache > NIL:");
  al_clean();
  if(keybufptr!=NULL){
    free(keybufptr);
    keybufptr=NULL;
  }
  if(buffer!=NULL){
     free(buffer);
     buffer=NULL;
  }
  if(display!=NULL){
     free(display);
     display=NULL;
  }
  if(IntuitionBase!=0)
    shutdown(); /* Close Window and screen safely */
  if(GfxBase!=0){
    if(font_ptr!=NULL)
      CloseFont(font_ptr);
    if(cfontptr!=NULL)
      CloseFont(cfontptr);
    if(ft_view.LOFCprList!=NULL)
      FreeCprList( ft_view.LOFCprList );
    if(sec_view.LOFCprList!=NULL)
      FreeCprList( sec_view.LOFCprList );
    if(ft_view.SHFCprList!=NULL)
      FreeCprList( ft_view.SHFCprList );
    if(sec_view.SHFCprList!=NULL)
      FreeCprList( sec_view.SHFCprList );
    FreeVPortCopLists(&ft_viewport );
    FreeVPortCopLists(&sec_viewport);
    /* Because both screens are interlaced they have two seperate
       copperlists, stored in the "view.SHFCprList" */
    for( loop = 0; loop < DEPTH; loop++ ){
      if( ft_bitmap.Planes[ loop ] )
        FreeRaster( ft_bitmap.Planes[ loop ], WIDTH, HEIGHT );
    }
    for( loop = 0; loop < DEPTH; loop++ ){
      if( sec_bitmap.Planes[ loop ] )
        FreeRaster( sec_bitmap.Planes[ loop ], WIDTH, HEIGHT );
    }
    for( loop = 0; loop < DEPTH; loop++ ){
      if( thd_bitmap.Planes[ loop ] )
        FreeRaster( thd_bitmap.Planes[ loop ], WIDTH, THDHITE );
    }
    if(wb_version>=37){
      if(ft_vextra!=NULL)
        GfxFree(ft_vextra);
      if(sec_vextra!=NULL)
        GfxFree(sec_vextra);
      if(vpone_extra!=NULL)
        GfxFree(vpone_extra);
      if(vptwo_extra!=NULL)
        GfxFree(vptwo_extra);
      if(monspec!=NULL)
        CloseMonitor( monspec );
    }
    if( ft_viewport.ColorMap != NULL )
      FreeColorMap( ft_viewport.ColorMap );
    if( sec_viewport.ColorMap != NULL )
      FreeColorMap( sec_viewport.ColorMap );
  }
  if( aport ) {
    DeleteMsgPort(aport);  /* Exec Library Routine */
    aport=NULL;
  }
  if( ConsoleDevice != NULL)
    CloseDevice( (struct IORequest *) &ioreq);
  if( DiskfontBase !=0)
    CloseLibrary(DiskfontBase);
  if( WorkbenchBase !=0)
    CloseLibrary(WorkbenchBase);
  if( GfxBase != 0)
    CloseLibrary( (struct Library *) GfxBase );
  if( IntuitionBase != 0)
    CloseLibrary( IntuitionBase );
  #ifdef TEST
    write_log("Cleanup PASSED\n",PRIONE);
  #endif
}

void alert(TEXT *message)
{
   #ifdef TEST
     write_log("Alert MESSAGE: ",PRIONE);
     write_log(message,PRIONE);
   #endif
   perror(message);
   cleanup();
   exit(20);
}

void shutdown(void){
  if(my_window!=NULL)
    CloseWindow(my_window);
  if(my_screen!=NULL)
    CloseScreen(my_screen);
  #ifdef TEST
    write_log("shutdown PASSED\n",PRITHREE);
  #endif
}
