// E51-Codecs.cpp -- demonstrates the use of Codecs to encode and decode byte streams
//  usage: ./E51-Codecs <e | d> <lzss | rle | rle64k> infile outfile

#include <Platform.h>
using namespace Platform;
using namespace Platform::Containers;
using namespace Platform::Io;


//====================================================================================================
AppMain(args)
{
    if(args.size() < 5)
    {
        Runtime::StdOut::fprintln(appText("Usage is: %s <e | d> <lzss | rle | rle64k> infile outfile"), args[0].value());
        return 1;
    }

    Bool encode = args[1] == appText("e");

    File inFile(Path(args[3]), FileMode_Open, FileAccess_Read);
    File outFile(Path(args[4]), FileMode_TruncateOrCreate);

    BufferedStream ioStream(&inFile, &outFile);

    DateTime start;

    if(args[2] == appText("lzss"))
    {
        Util::Codec::LZSS codec(&ioStream);

        encode ? codec.encode() : codec.decode();
    }
    else if(args[2] == appText("rle1"))
    {
        Util::Codec::RLE1 codec(&ioStream);

        encode ? codec.encode() : codec.decode();
    }
    else if(args[2] == appText("rle2"))
    {
        Util::Codec::RLE2 codec(&ioStream);

        encode ? codec.encode() : codec.decode();
    }
    else
    {
        appAbort(appText("invalid compression mode"));
    }
    ioStream.flush();

    Runtime::StdOut::fprintln(appText("in: %qd, out: %qd, ratio: %.3f, time: %s"), inFile.size(), outFile.size(), Double(outFile.size()) / Double(inFile.size()), start.sample().format(appText("%h:%m:%s.%u")).value());

    return 0;
}


/* EOF */