// (c) 2005-2007 Electronic Arts Inc.

#include "stdgimex.h"
#include "stdgimex.cpp"
#if defined(_MSC_VER)
#include <windows.h>
#endif

typedef GPOS filesize_t;

// 2004.5.12 - allow 0 byte pad files.  more exact write error checking
// 2004.5.14 - int64, maxsize to allow multiple files to be generated on xbox, where a single file can not exceed 1 GB
// 2004.5.18 - use proper MB*1024*1024
// 2004.5.26 - seek to end and write 1 byte for speed and quick failure if disk is not big enough
// 2004.5.27 - append # to end of name before extension
// 2004.6.01 - maxpad 2040
// 2005.1.31 - iso file to diff size from
// 2005.2.16 - remove upper limit by default
// 2005.9.19 - SetEndOfFile for PC
// 2007.11.14 - filepad based on makepad
// 2007.11.15 - more verbose

//
//  ABSTRACT
//
//  filepad - make a padfile of specified size
//
//  SUMMARY
//
//  filepad <file.pad> <size> <maxsize>
//  <file.pad> Name of file to create
//  <size>     Size of padding in bytes
//
//  DESCRIPTION
//
//  filepad appends zeros to the end of a file to make the size aligned to the specified amount.  Default is 32768 which helps DVD layouts
//
//  RETURNS
//
//  0 always returns 0
//
//  SEE ALSO
//
//  makepad, du
//
//  END ABSTRACT
//

void alignfile(const char *filename,filesize_t alignment)
{
    GSTREAM *g = gopen(filename);
    filesize_t originalfilesize = glen(g);
    gclose(g);

    filesize_t newfilesize = (originalfilesize+alignment-1)/alignment*alignment;
    filesize_t padamount = newfilesize-originalfilesize;
    if (padamount)
    {
        GSTREAM *gw = grwopen(filename);
        gseek(gw,newfilesize-1);
        gwrite(gw,"\0",1);
        gclose(gw);
    }
    printf("file %s padded by %d bytes%s\n", filename, (int)padamount, padamount?".":" (no change)");
}

int main(int argc, char **argv)
{
    if(argc<2)
    {
        printf(
            "filepad 2007.11.15 by Frank Barchard\n"
            "USAGE: filepad <file.bin> <size>\n"
            "  -<size>     Size to pad file to in bytes.  Default is 32768\n"
            "  <files.bin> Names of file to pad\n"
            );
        exit(1);
    }
    filesize_t alignment = 32768;

    for (int i=1; i<argc; ++i)
    {
        if (argv[i][0]=='-')
        {
#if defined(_MSC_VER)
            alignment = _atoi64(argv[i]);
#else
            alignment = (filesize_t) atoll(argv[i]);   // long long is hopefully 64 or more bits
#endif
            if (alignment<0)
                alignment = -alignment;
            if (!alignment) alignment = 32768;
        }
        else
        {
            alignfile(argv[i],alignment);
        }
    }


    return 0;
}
