#include <time.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <io.h>
#include <share.h>
#include <alloc.h>
#include <sys\stat.h>
#include <fcntl.h>
#include <string.h>
#include <process.h>
#include <stdarg.h>
#include <conio.h>


#define FLTMAXSIZE 2048
#define VAR_CHAR '@'

#define H_STRING  1
#define H_INTEGER 2
#define H_LONGINT 3

size_t commafmt(char   *buf,            /* Buffer for formatted string  */
                int     bufsize,        /* Size of buffer               */
                long    N)              /* Number to convert            */
{
        int len = 1, posn = 1, sign = 1;
        char *ptr = buf + bufsize - 1;

        if (2 > bufsize)
        {
ABORT:          *buf = '\0';
                return 0;
        }

        *ptr-- = '\0';
        --bufsize;
        if (0L > N)
        {
                sign = -1;
                N = -N;
        }

        for ( ; len <= bufsize; ++len, ++posn)
        {
                *ptr-- = (char)((N % 10L) + '0');
                if (0L == (N /= 10L))
                        break;
                if (0 == (posn % 3))
                {
                        *ptr-- = ',';
                        ++len;
                }
                if (len >= bufsize)
                        goto ABORT;
        }

        if (0 > sign)
        {
                if (0 == bufsize)
                        goto ABORT;
                *ptr-- = '-';
                ++len;
        }

        strcpy(buf, ++ptr);
        return (size_t)len;
}


char *handle_string(int type, void *variable, int justlength, char justtype, char fillchar, char commait, int soffset)
{
    char *newstring;
    char formstring[50];
    char comma_num[20];
    char justchar = '-';


    if(justtype == 'L') justchar = '-';
    else
    if(justtype == 'R') justchar = '+';
    else
    if(justtype == 'C') justchar = '-';

    if((newstring = (char *)malloc(justlength+1)) == NULL)
        return("");

    switch(type) {
        case H_STRING: // String
            sprintf(formstring, "%%%c%d.%ds", justchar, justlength, justlength);
            sprintf(newstring, formstring, (char *)variable);
            break;
        case H_INTEGER: // Integer
            if(commait)
            {
                long templong = (*(int *)variable);
                sprintf(formstring, "%%%c%d.%ds", justchar, justlength, justlength);
                commafmt(comma_num,20,templong);
                sprintf(newstring, formstring, comma_num);
            }
            else
            {
                sprintf(formstring, "%%%c%d.%dd", justchar, justlength, justlength);
                sprintf(newstring, formstring, *((int *)variable));
            }
            break;
        case H_LONGINT: // Longint
            if(commait)
            {
                commafmt(comma_num,20,*((long *)variable));
                sprintf(formstring, "%%%c%d.%ds", justchar, justlength, justlength);
                sprintf(newstring, formstring, comma_num);
            }
            else
            {
                sprintf(formstring, "%%%c%d.%dld", justchar, justlength, justlength);
                sprintf(newstring, formstring, *((long *)variable));
            }
            break;
        }


/*    if(justtype == 'C' && justlength > 2) // Center string
    {
        int startpos = 0;

        if(justlength % 2 == 0)
            startpos = (justlength / 2) -
        else
            startpos =


    }
*/

            // Change fill character if necessary
            if(fillchar != ' ')
            {
                    if(justtype == 'L' || justtype == 'C')
                    {
                    for(int tc=0;newstring[++tc] == ' ';)
                        if(newstring[tc] == ' ')
                           newstring[tc] = fillchar;
                   }
                 if(justtype == 'R' || justtype == 'C')
                    {
                    for(int tc=strlen(newstring)-1;newstring[--tc]==' ';)
                        if(newstring[tc] == ' ')
                           newstring[tc] = fillchar;

                    }
            }

return(&newstring[soffset]);
}

int determine_newsize(char *inbuf)
{
int newsize = 0;
char basename[60];
int soffset = 0;
int justlength;
char varname[80];
int counter2;
char justtype,commait,padchar;

    for(int counter=0; counter < strlen(inbuf); counter++)
    {
        if(inbuf[counter] == VAR_CHAR) // Variable start
        {
            if(inbuf[counter+1] == VAR_CHAR)
            {
                counter++;      // Skip @@
                newsize++;      // Still count it though
            }
            else    // Process variable
            {       
                counter++; // Skip '@'
                for(counter2=0;inbuf[counter] != VAR_CHAR && counter2 < 80 && counter < strlen(inbuf);counter2++,counter++)
                {
                    varname[counter2] = inbuf[counter];
                }
                varname[counter2] = 0;

                justlength = -1;
                justtype = 'L';
                commait = 'N';
                padchar = ' ';
                soffset = 0;

                sscanf(varname,"%s %d,%c,%c,%c,%d",&basename,&justlength,&justtype,&commait,&padchar,&soffset);

                if(justlength == -1)
                    {
                        if(strcmpi(basename,"A") == 0)
                            justlength=5;
                        else
                        if(strcmpi(basename,"AREANAME") == 0)
                            justlength=30;
                        else
                        if(strcmpi(basename,"FILES") == 0)
                            justlength=5;
                        else
                        if(strcmpi(basename,"TDLS") == 0)
                            justlength=6;
                        else
                        if(strcmpi(basename,"AREABYTES") == 0)
                            justlength=12;
                        else
                        if(strcmpi(basename,"P") == 0)
                            justlength=3;
                        else
                        if(strcmpi(basename,"POPULAR") == 0)
                            justlength=12;
                        else
                        if(strcmpi(basename,"POPSIZE") == 0)
                            justlength=9;
                        else
                        if(strcmpi(basename,"POPDESC") == 0)
                            justlength=46;
                    }

                newsize+=justlength;

                memset(basename,0,60);
                memset(varname,0,80);
            }
        }
        else    // Normal character
        {
            newsize++;
        }
    }

return(newsize);
}

//
//  Processes a header buffer..... converting control codes, etc.
//
//      outbuf should be a pointer of an unallocated amount.
//
int process_header(char *inbuf, char *outbuf, unsigned int areanumber, char areaname[30], unsigned int areafiles, unsigned int areadownloads, long areabytes, unsigned int mostpopulardownloads, char mostpopular[13], long mostpopularsize, char mostpopulardesc[FLTMAXSIZE+1])
{
int counter2;
char basename[60];
int justlength;
char varname[80];
int soffset = 0;
int counter;
char justtype,commait,padchar;


    for(counter=0; counter < strlen(inbuf)-1; counter++)
    {
        if(inbuf[counter] == VAR_CHAR) // Variable start
        {
            if(inbuf[counter+1] == VAR_CHAR)
            {
                counter++;      // Skip @@
                outbuf[strlen(outbuf)+1] = 0;
                outbuf[strlen(outbuf)] = VAR_CHAR;
            }
            else    // Process variable
            {       
                counter++; // Skip '@'
                for(counter2=0;inbuf[counter] != VAR_CHAR && counter2 < 80 && counter < strlen(inbuf);counter2++,counter++)
                {
                    varname[counter2] = inbuf[counter];
                }
                varname[counter2] = 0;

                justlength = -1;
                justtype = 'L';
                commait = 'N';
                padchar = ' ';
                soffset = 0;

                sscanf(varname,"%s %d,%c,%c,%c,%d",&basename,&justlength,&justtype,&commait,&padchar,&soffset);

                if(justlength == -1)        // Use Defaults
                    {
                        if(strcmpi(basename,"A") == 0)
                            justlength=5;
                        else
                        if(strcmpi(basename,"AREANAME") == 0)
                            justlength=30;
                        else
                        if(strcmpi(basename,"FILES") == 0)
                            justlength=5;
                        else
                        if(strcmpi(basename,"TDLS") == 0)
                            justlength=6;
                        else
                        if(strcmpi(basename,"AREABYTES") == 0)
                            justlength=12;
                        else
                        if(strcmpi(basename,"P") == 0)
                            justlength=3;
                        else
                        if(strcmpi(basename,"POPULAR") == 0)
                            justlength=12;
                        else
                        if(strcmpi(basename,"POPSIZE") == 0)
                            justlength=9;
                        else
                        if(strcmpi(basename,"POPDESC") == 0)
                            justlength=46;
                    }

                        if(strcmpi(basename,"A") == 0)
                            strcat(outbuf,handle_string(H_INTEGER,&areanumber,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"AREANAME") == 0)
                            strcat(outbuf,handle_string(H_STRING,areaname,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"FILES") == 0)
                            strcat(outbuf,handle_string(H_INTEGER,&areafiles,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"TDLS") == 0)
                            strcat(outbuf,handle_string(H_INTEGER,&areadownloads,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"AREABYTES") == 0)
                            strcat(outbuf,handle_string(H_LONGINT,&areabytes,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"P") == 0)
                            strcat(outbuf,handle_string(H_INTEGER,&mostpopulardownloads,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"POPULAR") == 0)
                            strcat(outbuf,handle_string(H_STRING,mostpopular,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"POPSIZE") == 0)
                            strcat(outbuf,handle_string(H_LONGINT,&mostpopularsize,justlength,justtype,padchar,commait,soffset));
                        else
                        if(strcmpi(basename,"POPDESC") == 0)
                            strcat(outbuf,handle_string(H_STRING,mostpopulardesc,justlength,justtype,padchar,commait,soffset));
            }
            memset(basename,0,60);
            memset(varname,0,80);

        }
        else    // Normal character
        {
            outbuf[strlen(outbuf)+1] = 0;
            outbuf[strlen(outbuf)] = inbuf[counter];
        }
    }

    return(1);
}

void view_with_color(char *buffer,int bufsize)
{
char ch;
char hexstring[2];
int attrib;
memset(hexstring,0,3);

    for(int x=0;x<bufsize-1;x++)
    {
        if(buffer[x] == '')
        {
            if(buffer[x+1] == 'b')
               if(((hexstring[0]=buffer[x+2]) != NULL) && ((hexstring[1]=buffer[x+3]) != NULL))
               {
                      sscanf(hexstring,"%x",&attrib);
                      textattr(attrib);
               x+=3;
               }

        }
        else
          if(buffer[x] == 10)
          {
            putch(13);
            putch(10);
          }
          else
            putch(buffer[x]);
    }
}

main(int argc, char *argv[])
{
    int instream;
    char header[4000];
    char *outbuf;

    directvideo = 1;

    instream=sopen(argv[1],O_RDONLY,SH_DENYNO);
    header[read(instream,&header,4000)+1] = 0;
    close(instream);

    int newsize = determine_newsize(header);

    printf("\r\nOld Size: %d\r\n", strlen(header));
    printf("\r\nNew Size: %d\r\n", newsize);


    if((outbuf = (char *)malloc(newsize)) == NULL)
        return(0);

    memset(outbuf,0,newsize);

    process_header(header,outbuf,3,"New Uploads",322,569,59029321,54,"DOOM.ZIP",2349210,"The Ultimate in 3-d games");

    int stream2=sopen(argv[2],O_WRONLY|O_CREAT|O_TRUNC,SH_DENYNO,S_IWRITE);
    write(stream2,outbuf,newsize-1);
    close(stream2);

//    view_with_color(outbuf,newsize-1);

    free(outbuf);

}
