//  CHAR_AUX.C
//  Auxiliary string functions
//  © 2021 Peter J. Meyer

#include "iss.h"

static char *sltoa_intl(long x, char *str, char sep);
static char *ultoa_intl(unsigned long x, char *str, char sep);

//  This moves the pointer at *p to the first character past the last space.
//  Tab characters are treated as spaces.
/*-----------------------*/
void skip_spaces(char** pp)		//  a pointer to a pointer to a char
{
while ( **pp == ' ' || **pp == TAB )
	(*pp)++;
}

/*---------------------------------*/
void remove_leading_spaces(char *str)
{
char *start = str;
        
skip_spaces(&str);
move_str_left(start,str);
}

//  Copy bytes at str1 to str until 0 byte is copied.
/*-------------------------------------*/
void move_str_left(char *str1, char *str2)
{
if ( str1 > str2 )
	return;

while ( true )
    {
    if ( !( *(str1++) = *(str2++) ) )
        break;
    }           
}  

//  This treats tab characters as spaces.
/*----------------------------------*/
void remove_trailing_spaces(char *str)
{             
char *ptr = str;

while ( *ptr )
    ptr++;      

while ( ptr-- > str )
    {
    if ( ( *ptr != SPACE ) && ( *ptr != TAB ) )
        break;
    *ptr = 0;  
    }        
}         

/*-------------------------------*/
void remove_outer_spaces(char *str)
{
remove_trailing_spaces(str);
remove_leading_spaces(str);
}   

/*------------------*/
void spaces(char *str,
            int num_spaces)
{
if ( num_spaces < 0 )
    return;

str[num_spaces] = 0;

while ( --num_spaces >= 0 )
    str[num_spaces] = SPACE;
}

//  This removes all trailing zeros from the end of number
//  except for a zero following a decimal point.
/*-------------------------------------*/
void remove_trailing_zeros(char *num_str)
{             
char *ptr = num_str;

while ( *ptr )
    ptr++;      

while ( ptr-- > num_str )
    {
    if ( *ptr != '0' )
        break;
    *ptr = 0;  
    } 

while ( *ptr )
    ptr++;      
    
if ( *(ptr-1) == '.' )
    {
    *(ptr++) = '0';
    *ptr = 0;
    }          
}   

//  Call with format = 0 for ISO date format,
//  1 for European date format, 2 for U.S. date format.
/*-----------------------------*/
char *system_date(char *date_str, 
                  int format)
{
int day, month, year;

_strdate(date_str);     //  "mm/dd/yy" in date_str
month = atoi(date_str);
day = atoi(&date_str[3]);
year = atoi(&date_str[6]);
year += ( year < 80 ? 2000 : 1900 );

switch ( format )   
    {
    case ISO:
    sprintf(date_str,"%04d-%02d-%02d",year,month,day);
    break;

    case EUR:
    sprintf(date_str,"%04d/%02d/%02d",day,month,year);
    break;

    case US:
    sprintf(date_str,"%04d/%02d/%02d",month,day,year);
    break;
    }

return ( date_str );
}

//  Call with seconds = true to include seconds.
/*-----------------------------*/
char *system_time(char *time_str, 
                  int seconds)
{
_strtime(time_str);     //  "hh:mm:ss" in time_str

if ( !seconds )
    time_str[5] = 0;

return ( time_str );
}

/*----------------------*/
char *sltoa_commas(long x,
                   char *str)
{
return ( sltoa_intl(x,str,',') );
}

/*---------------------------*/
static char *sltoa_intl(long x,
                        char *str,
                        char sep)
{
if ( x < 0 )
    {
    strcpy(str,"-");
    x = labs(x);
    ultoa_intl(x,str+1,sep);
    }
else
    ultoa_intl(x,str,sep);

return ( str );
}

/*-------------------------------*/
char *ultoa_commas(unsigned long x,
                   char *str)
{
return ( ultoa_intl(x,str,',') );
}

/*------------------------------------*/
static char *ultoa_intl(unsigned long x,
                        char *str,
                        char sep)
{
int i;
char thousands[4][4];
char scratch6[6], sep_str[2];

sep_str[0] = sep;
sep_str[1] = 0;

*str = 0;
i = 0;

while ( x >= 1000 )
    {
    sprintf(thousands[i++],"%03d",x%1000);
    x /= 1000;
    }
itoa((int)x,scratch6,10);
strcat(str,scratch6);
while ( --i >= 0 )
    {
    strcat(str,sep_str);
    strcat(str,thousands[i]);
    }
return ( str );
}

//  Converts a number of seconds to days, hours, minutes, seconds.
/*------------------------------------------------*/
char *seconds_to_time_str(unsigned long num_seconds,
                          char *time_str)
{
int days, hours, minutes, seconds;
char tempstr[16];

*time_str = 0;

if ( num_seconds >= 0 )
    {
    days = num_seconds/86400L;
    num_seconds %= 86400;
    hours = num_seconds/3600;
    num_seconds %= 3600;
    minutes = num_seconds/60;
    seconds = num_seconds%60; 

    if ( days )
        sprintf(time_str,"%d day%s, ",days,(days==1?"":"s"));

    if ( hours )
        {
        sprintf(tempstr,"%d hour%s, ",hours,(hours==1?"":"s"));
        strcat(time_str,tempstr);
        }

    if ( minutes )
        {
        sprintf(tempstr,"%d minute%s, ",minutes,(minutes==1?"":"s"));
        strcat(time_str,tempstr);
        }

    if ( seconds )
        {
        sprintf(tempstr,"%d second%s, ",seconds,(seconds==1?"":"s"));
        strcat(time_str,tempstr);
        }

    if ( days || hours || minutes || seconds )
        *strrchr(time_str,',') = 0;
    else
        strcpy(time_str,"0 seconds");
    }

return ( time_str );
}