#include <TROOT.h>
#include <TClass.h>
#include <TGClient.h>
#include <TApplication.h>

#include "MLog.h"
#include "MLogManip.h"

#include "MArgs.h"

#include "MStatusDisplay.h"

using namespace std;

static void StartUpMessage()
{
    //                1         2         3         4         5
    //       12345678901234567890123456789012345678901234567890
    gLog << endl;
    gLog << "showplot --- Mars V" << MARSVER << " compiled on <" << __DATE__ << "> using ROOT v" << ROOTVER << endl;
    gLog << endl;
}

static void Usage()
{
    //                1         2         3         4         5         6         7         8
    //       12345678901234567890123456789012345678901234567890123456789012345678901234567890
    gLog << all << endl;
    gLog << "Sorry the usage is:" << endl;
    gLog << " showplot [options] filename" << endl << endl;
    gLog << " Arguments:" << endl;
    gLog << "   filename                  Input file containing an MStatusArray" << endl << endl;
    gLog << " Root Options:" << endl;
    gLog << "   -b                        Batch mode (no graphical output to screen)" << endl<<endl;
    gLog << " Options: "<< endl;
    gLog.Usage();
    gLog << "   -q                        Quit when job is finished" << endl;
    gLog << endl;
    gLog << " Output Options: "<< endl;
    gLog << "   --save-as-ps[=filename]   Save plots as postscript" << endl;
    gLog << "   --save-as-gif[=filename]  Save plots as gif files" << endl;
    gLog << "   --save-as-C[=filename]    Save plots as root scripts" << endl;
    gLog << "   --tab=num                 Save only tab number num" << endl << endl;
    gLog << "Description:" << endl;
    gLog << " Use showplot to display a MStatusArray in an MStatusDisplay." << endl;
    gLog << " MStatusArrays are typically written by programs showing data" << endl;
    gLog << " check plots, like callisto." << endl;
    gLog << endl;
}

int main(int argc, char **argv)
{
    StartUpMessage();

    //
    // Evaluate arguments
    //
    MArgs arg(argc, argv, kTRUE);

    if (arg.HasOnly("-?") || arg.HasOnly("-h") || arg.HasOnly("--help"))
    {
        Usage();
        return -1;
    }

    gLog.Setup(arg);

    const Bool_t kQuit      = arg.HasOnlyAndRemove("-q");
    const Bool_t kBatch     = arg.HasOnlyAndRemove("-b");

    const Int_t  kTab       = arg.GetIntAndRemove("--tab=", -1);

    const Bool_t kSaveAsPs  = arg.HasOnlyAndRemove("--save-as-ps")  || arg.Has("--save-as-ps=");
    const Bool_t kSaveAsGif = arg.HasOnlyAndRemove("--save-as-gif") || arg.Has("--save-as-gif=");
    const Bool_t kSaveAsC   = arg.HasOnlyAndRemove("--save-as-C")   || arg.Has("--save-as-C=");

    TString kNamePs  = arg.GetStringAndRemove("--save-as-ps=");
    TString kNameGif = arg.GetStringAndRemove("--save-as-gif=");
    TString kNameC   = arg.GetStringAndRemove("--save-as-C=");


    //
    // check for the right usage of the program
    //
    if (arg.GetNumArguments()!=1)
    {
        Usage();
        return -1;
    }

    TApplication app("Showplot", &argc, argv);
    if (!gROOT->IsBatch() && !gClient || gROOT->IsBatch() && !kBatch)
    {
        gLog << err << "Bombing... maybe your DISPLAY variable is not set correctly!" << endl;
        return 1;
    }

    //
    // Process filenames
    //
    const TString kInput = arg.GetArgumentStr(0);

    if (kNamePs.IsNull()  && kSaveAsPs)
        kNamePs = kInput;
    if (kNameGif.IsNull() && kSaveAsGif)
        kNameGif = kInput;
    if (kNameC.IsNull()   && kSaveAsC)
        kNameC = kInput;

    //
    // Update frequency by default = 1Hz
    //
    MStatusDisplay *d = new MStatusDisplay;

    // From now on each 'Exit' means: Terminate the application
    d->SetTitle(kInput);
    d->Open(kInput);

    if (kSaveAsPs)
        d->SaveAsPS(kTab, kNamePs);
    if (kSaveAsGif)
        d->SaveAsGIF(kTab, kNameGif);
    if (kSaveAsC)
        d->SaveAsC(kTab, kNameC);

    if (kBatch || kQuit)
    {
        delete d;
        return 0;
    }

    // From now on each 'Close' means: Terminate the application
    d->SetBit(MStatusDisplay::kExitLoopOnClose);

    // Wait until the user decides to exit the application
    app.Run(kFALSE);
    return 0;
}
