/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef SCRIPT_H__
#define SCRIPT_H__

//#pragma once

#include "macro.h"
#include "MvRequest.h"


class Script : public Context
{
    char* runmode;
    static char* macropath;
    static char* macroMainPath;

public:
    // It contains the last macro function that has been compiled
    static void MacroPath(const char* p)
    {
        strfree(macropath);
        macropath = strcache(p);
    }
    static const char* MacroPath() { return macropath; }

    // It contains the full path of the macro
    static void MacroMainPath(const char* p)
    {
        strfree(macroMainPath);
        macroMainPath = strcache(p);
    }
    static const char* MacroMainPath() { return macroMainPath; }

    static Value Driver;       //-- uPlot
    static Value Output;       //-- PlotMod
    static Value Device;       //-- VisMod
    static MvRequest PlotReq;  //-- Plot request
    static Script* Compiled;
    static svcid* SvcId;
    static void PutMessage(int, const char*);
    static void PutExtendedMessage(int, const char*);

    virtual void CompileError(const char*, int);
    int Compile(const char* = NULL);

    Script(const char*);
    ~Script();

    void SetRunMode(const char* m)
    {
        strfree(runmode);
        runmode = strcache(m);
    }
    const char* GetRunMode(void) { return runmode; }

    void AddBaseLanguageGlobalVar(void) { AddGlobal(new Variable("base_language", Value(Context::BaseLanguage()))); }
};

//============================================================================

class Terminal : public Script
{
    Step* last;
    virtual void NewStep(Step* s);
    virtual Step* FirstStep(void) { return last; };

public:
    Terminal(const char* n) :
        Script(n)
    {
        last = NULL;
        SetRunMode("interactive");
    };
};


//============================================================================

class Module : public Script
{
    svc* Svc;
    static void Serve(svcid*, request*, void*);

public:
    Module(const char* name);
    void Dispatch(svcid*, request*);

    virtual Value Run(const char* handler, int argc = 0, Value* argv = NULL);
};

//============================================================================

class Compute : public Script
{
    math* Math;

    void rename(math*, char*, const char*);
    void import(FILE*, math*, request*);
    void write(FILE*, math*);


public:
    Compute(const char* name, request* r);
    ~Compute();
};

//============================================================================
class Formula : public Script
{
public:
    Formula(const char* name, request* r);
    ~Formula();
};

//============================================================================

class Batch : public Script
{
    svc* batch;
    virtual void CompileError(const char*, int);
    virtual void RuntimeError(const char*, int);
    static void BatchError(int, void*);

public:
    Batch(const char* name);
    ~Batch();
};

#endif
//SCRIPT_H__
