
/*
**  This file forms part of the GOBLIN C++ Class Library.
**
**  Written by Christian Fremuth-Paeger, May 1999.
**  
**  Copying, compiling, distribution and modification
**  of this source code is permitted only in accordance
**  with the GOBLIN general licence information.
*/


#if !defined(_CONTEXT_H_)

#define _CONTEXT_H_

#include <globals.h>



const unsigned long goblinRandMax   = RAND_MAX;


class goblinAbstractObject
{
public:
    
    goblinAbstractObject() {goblinNObjects++;};
    virtual ~goblinAbstractObject() {goblinNObjects--;};

    virtual char*           Display() throw(ERFile,ERRejected) = 0;
    virtual char*           Label() throw() = 0;
    virtual unsigned long   Size() throw() = 0;
    virtual bool            IsGraphObject() {return false;};
    virtual bool            IsMixedILP() {return false;};
    virtual objectType      ClassID() throw() {return IDUnknown;};
    virtual void*           BackCast() {return NULL;};


    // *************************************************************** //
    //                     Local Type Declarations                     //
    // *************************************************************** //

    enum TOwnership {OWNED_BY_SENDER = 1,OWNED_BY_RECEIVER = 0};

#if defined(_HEAP_MON2_)

    // *************************************************************** //
    //                       Memory Management                         //
    // *************************************************************** //

    void* operator new(size_t size) throw (std::bad_alloc);
    void* operator new[](size_t size) throw (std::bad_alloc);
    void* GoblinRealloc(void* p,size_t size) throw (std::bad_alloc);
    void operator delete(void *p) throw ();
    void operator delete[](void *p) throw ();

#endif

};


class goblinController : public virtual goblinAbstractObject
{
friend class goblinExport;
friend class goblinILPWrapper;
private:
    
    int         externalPrecision;
    int         externalFloatLength;
    TNode       maxNode;
    TArc        maxArc;
    THandle     maxHandle;
    TIndex      maxIndex;
    long int    maxInt;
    
    void    (*savedLogEventHandler)(msgType,THandle,char*);
    int     savedTraceLevel;

    int            breakPoint;
    unsigned long  traceCounter;
    
    bool        isDefault;
    
public:

    goblinController() throw();
    goblinController(goblinController&) throw();
    virtual ~goblinController() throw();
    
    char*           Display() throw(ERFile,ERRejected) {return NULL;};
    
    int             FindParam(int pc,char* pStr[],char* token) throw();
    void            Configure(int ParamCount,char* ParamStr[]) throw();

    void            ReadConfiguration(char*) throw(ERFile,ERParse);
    void            WriteConfiguration(char*) throw(ERFile);
    
    char*           objectExtension;

    TNode           sourceNode;
    TNode           targetNode;
    TNode           rootNode;

    
    // *************************************************************** //
    //           Module Management                                     //
    // *************************************************************** //
    
    static const int    majorVersion;
    static const int    minorVersion;
    static const char   patchLevel[];

    static void const*  pLPModule;

    
    // *************************************************************** //
    //           Memory Management                                     //
    // *************************************************************** //
    
    bool            checkMem;

    unsigned long   Size() throw();


    // *************************************************************** //
    //           Object Management                                     //
    // *************************************************************** //

    goblinAbstractObject*   masterObject;
    THandle                 masterHandle;
    THandle                 objCounter;
    goblinAbstractObject**  pObject;

    THandle         InsertObject(goblinAbstractObject*) throw(ERRejected);
    goblinAbstractObject* ObjectPointer(THandle) throw(ERRejected);
    void            DeleteObject(THandle) throw(ERRejected);
    void            StripObjects() throw();
    void            SetMaster(THandle) throw(ERRejected);
    THandle         Master() throw(ERCheck);
    char*           Label() throw();


    // *************************************************************** //
    //           Logging                                               //
    // *************************************************************** //

    int     logMeth;
    int     logMem;
    int     logMan;
    int     logIO;
    int     logRes;
    int     logWarn;

    int     logDepth;
    int     logLevel;
    bool    logCont;
    
    void IncreaseLogLevel() throw(ERRejected);
    void DecreaseLogLevel() throw(ERRejected);
    void SuppressLogging() throw();
    void RestoreLogging() throw();
    
    ostream* logStream;
    void (*logEventHandler)(msgType,THandle,char*);

    void PlainLogEventHandler(msgType,THandle,char*) throw();
    void DefaultLogEventHandler(msgType,THandle,char*) throw();
    
    char logBuffer[LOGBUFFERSIZE];
    
    void LogEntry(msgType,THandle,char*) throw();
    void LogAppend(char*) throw();


    // *************************************************************** //
    //           Error Handling                                        //
    // *************************************************************** //

    void Error(msgType,THandle,char*,char*)
        throw(ERRange,ERRejected,ERCheck,ERFile,ERParse);

    char     savedErrorMethodName[LOGBUFFERSIZE];
    char     savedErrorDescription[LOGBUFFERSIZE];
    THandle  savedErrorOriginator;
    msgType  savedErrorMsgType;
    
    // *************************************************************** //
    //           Graph Browser                                         //
    // *************************************************************** //

    int    displayMode;
    int    hiddenObjects;
    
    int    xShift;
    int    yShift;
    double xZoom;
    double yZoom;
    
    int    nodeSize;
    int    arrowSize;
    int    legenda;
    int    nodeSep;

    int    nodeStyle;
    int    nodeLabels;
    int    nodeColours;
    int    arcStyle;
    int    arcLabels;
    int    arcLabels2;
    int    arrows;
    int    arrowColours;
    int    subgraph;
    int    predecessors;

    
    // *************************************************************** //
    //           Tracing                                               //
    // *************************************************************** //

    int     traceLevel;
    int     commLevel;
    int     breakLevel;
    int     traceData;
    int     threshold;
    int     fileCounter;
    int     traceStep;

    void    Ping(THandle HH,unsigned long priority) throw(ERRejected);
    void    ResetCounters() throw();
    void    IncreaseCounter()
        {if (fileCounter<10000) fileCounter++; else fileCounter = 0;};

    void (*traceEventHandler)(char*);

    
    // *************************************************************** //
    //           Selection of mathematical methods                     //
    // *************************************************************** //

    int     methFailSave;
    int     methGeometry;
    int     methSearch;
    int     methAdjacency;
    int     methMaxFlow;
    int     methMinCut;
    int     methMinCFlow;
    int     methMinCCirc;
    int     methMinTree;
    int     meth1Tree;
    int     methMaxBalFlow;
    int     methBNS;
    int     methDSU;
    int     methPQ;
    int     methTSP;
    int     methLocal;
    int     methSolve;
    int     methMinCBalFlow;
    int     methPrimalDual;
    int     methModLength;
    int     methCandidates;
    int     methColour;
    int     methRelaxTSP1;
    int     methRelaxTSP2;

    int     methLP;
    int     methLPPricing;
    int     methLPQTest;
    int     methLPStart;

    int     maxBBIterations;
    int     maxBBNodes;

    bool (*stopSignalHandler)();
    
    bool SolverRunning() throw();

    
    // *************************************************************** //
    //           Random Generators                                     //
    // *************************************************************** //
    
    unsigned long   Rand(unsigned long) throw(ERRange);
    TFloat          Rand() throw();
    void            SetRandomBounds(long int,long int) throw(ERRejected);

    int     randMin;
    int     randMax;
    
    int     randUCap;
    int     randLCap;
    int     randLength;
    int     randGeometry;
    int     randParallels;
    
    
    // Precision and External Number Formats
        
    TFloat  epsilon;
    TFloat  tolerance;
    
    void     SetExternalPrecision(int,int) throw(ERRejected);
    void     SetBounds(TNode,TArc,THandle,TIndex,long int) throw(ERRejected);
    TNode    MaxNode() throw() {return maxNode;};
    TArc     MaxArc() throw() {return maxArc;};
    THandle  MaxHandle() throw() {return maxHandle;};
    TIndex   MaxIndex() throw() {return maxIndex;};
    long int MaxInt() throw() {return maxInt;};

    char     ExternalIntLength(long int) throw();
    char     ExternalFloatLength(TFloat) throw();

};


extern goblinController goblinDefaultContext;


#endif
