#include	<pcdisk.h>
#include	<string.h>
#include	<time.h>

#include	"logtime.h"
#include	"text_log.h"


char *med_st[] = 
{ 
    "",
    "BAD_FORMAT",
    "CRERR_NO_CARD",
    "CRERR_BAD_CARD",
    "CRERR_CHANGED_CARD",
    "CRERR_CARD_FAILURE",
    "CRERR_ID_ERROR",
    "CRERR_ECC_ERROR" 
};


//  crit_err_n_tries counts the number of times we have tried since sending
//  the most recent ABORT return
static int crit_err_n_tries = 0;
static int crit_err_logging = 1;
static int crit_err_max_tries = 3;

void critical_error_reset (void)  {
	crit_err_n_tries = 0;
}


void critical_error_logging (int log)  {
	crit_err_logging = log;
}


void critical_error_set_n_tries (int n)  {
	crit_err_max_tries = n;
}
		


int critical_error_handler (int driveno, int media_status, dword sector)  {
	char inbuf[20];
	char outbuff[128];
	char serial[64];
	DDRIVE *pdr;
	BOOLEAN needs_flush;
	int n, multi_space, count;
	time_tt now;

	//  n_tries starts at 0 and is incremented each time through
	crit_err_n_tries++;

	//  Only print out information when logging is enabled.  We disable it only at
	//  the begining when we are scanning to determine which drives are present.
	if (crit_err_logging)  {
		now = logger_time_get_time ();
		log_printf ("critical_error_handler: disk error on try %d @ %s", crit_err_n_tries, ctime (&now.secs));
		#ifndef DEBUG
			printf ("critical_error_handler: disk error on try %d @ %s", crit_err_n_tries, ctime (&now.secs));
		#endif	

    	//  print the disk name and serial number, which are stored in a single char
    	//  array in the pdr structure.  Strip out the intervening spaces as we print,
    	//  cause they have no meaning for us.    
    	pdr = mem_drives_structures+driveno;
    	log_printf ("  Disk serial number: ");
    	count = 0;
    	for (n = 0;  n < 61;  n++)  {
    		if (pdr->drv_serial_number[n] != ' ')  {
    			multi_space = 0;
    			outbuff[count++] = pdr->drv_serial_number[n];
    		}  else  {
    			if (multi_space	== 0)
	    			outbuff[count++] = pdr->drv_serial_number[n];
	    		multi_space = 1;
	    	}
	    }
		outbuff[count++] = '\0';
		strcat (outbuff, "\n");
		log_printf ("%s", outbuff);
		
//    	strncpy (serial, (char*)pdr->drv_serial_number, 10);
//    	strcat (serial, " - ");
		//  strip spaces
//    	for (n = 11;  n < 61;  n++)  {
//    		if (pdr->drv_serial_number[n] != ' ')
//    			break;
//    	}
//    	strncat (serial, (char*)&pdr->drv_serial_number[n], 61-n);
//    	printf ("Disk error on serial number: %s\n", serial);
	    log_printf ("  Volume label is: %s\n", pdr->volume_label);
		log_printf ("  Media status == %s\n", med_st[media_status]);

	    if (pdr->fat_is_dirty || pc_test_all_fil(pdr))
    	    needs_flush = TRUE;
	    else
    	    needs_flush = FALSE;

//		ltemp = pdr->volume_serialno;
//		printf("Serial # == %X-%X\n", ltemp >> 16, ltemp & 0xffff);
	    if (needs_flush)
    	    log_printf ("  Volume is dirty\n");
	    else
    	    log_printf ("  Volume is clean\n");
    }	    

	if (crit_err_n_tries < crit_err_max_tries)  {
		if (crit_err_logging)  {
			log_printf ("  About to retry\n");
			#ifndef DEBUG
				printf ("  About to retry\n");
			#endif
		}
		return (CRITICAL_ERROR_RETRY);
	}	

	if (crit_err_logging)  {
	    log_printf ("  Have tried disk operation %d times.  Now aborting.\n", crit_err_n_tries);
		#ifndef DEBUG
			printf ("  Have tried disk operation %d times.  Now aborting.\n", crit_err_n_tries);
		#endif
	}
	return (CRITICAL_ERROR_ABORT);
}



/*
*****************************************************************************
    PC_GETSYSDATE - Get the current system time and date (USER SUPPLIED)

                    
Summary
    
    #include <pcdisk.h>

    DATESTR *pc_getsysdate(pd)
        DATESTR *pd;    put result here  


 Description
    When the system needs to date stamp a file it will call this routine
    to get the current time and date. YOU must modify the shipped routine
    to support your hardware's time and date routines. If you don't modify
    this routine the file date on all files will be the same.

    The source for this routine is in file pc_udate.c and is self explanatory.

    NOTE: Be sure to retain the property of returning its argument. The 
            package depends on it.

 Returns
    The argument it was passed. A structure containing date and time info.

Example:
    #include <pcdisk.h>

    DATESTR crdate; 

    Load the inode copy name,ext,attr,cluster, size,datetime
    pc_init_inode( pobj->finode, filename, fileext, 
                    attr, cluster, 0L ,pc_getsysdate(&crdate) );

*****************************************************************************
*/
#if (RTFS_WRITE)

#if (DOS)
#include <time.h>
#endif

/* get date and time from the host system   */
DATESTR *pc_getsysdate(DATESTR *pd)                                 /*__fn__*/
{
    word  year;     /* relative to 1980 */ 
    word  month;    /* 1 - 12 */ 
    word  day;      /* 1 - 31 */ 
    word  hour;
    word  minute;
    word  sec;      /* Note: seconds are 2 second/per. ie 3 == 6 seconds */
   	struct tm *timeptr;
	time_tt timer;

    timer = logger_time_get_time ();
    timeptr = localtime (&timer.secs); 
    hour = timeptr->tm_hour;
    minute = timeptr->tm_min;
    sec = timeptr->tm_sec / 2;
    //  Local time returns date relative to 1900, but the disk
    //  software wants it relative to 1980
    year = timeptr->tm_year - 80;
	month = timeptr->tm_mon + 1;
	day	= timeptr->tm_mday;
/*
    // This code is useless but very generic
    // Hardwire for now
    // 7:37:28 PM
    hour = 19;
    minute = 37;
    sec = 14;
    //3-28-88
    year = 8;       // relative to 1980
    month = 3;      // 1 - 12
    day = 28;       // 1 - 31
*/
    pd->time = (word) ( (hour << 11) | (minute << 5) | sec);
    pd->date = (word) ( (year << 9) | (month << 5) | day);
    return (pd);
}

#endif  /* RTFS_WRITE */

