#ifndef MAPPING_H
/*#pragma once*/
#pragma interface
#define MAPPING_H
#include "genmap.h"
#include "genfiles.h"
#include "gassign.h"
#include "hashtab.h"
#include "PSplayMap.h"

class SplayMap : public GenMap {
    friend class SplayMapFile;
  public:
    PtrPtrSplayMap map;
    size_t len;
    virtual size_t length() { return len; }
    virtual Root * prefix(Root *);
    SplayMap();
    SplayMap(Root *key1, Root *arg1);
    SplayMap(int n, Root **keys, Root **args);
//    virtual GenFile * open(long flags=0) const;
};

class MemoMap : public PrefixOp {
    // should probably be a subclass of both LVariable and SplayMap
  public:
    PtrPtrSplayMap map;
    Functional *rule;
    PtrPtrSplayMap *aux_map;
    MemoMap *link;
    MemoMap(Functional *);
    virtual Root *prefix(Root *arg);
    virtual void printon(ostream&) const;
};

class MemoSubSeq : public GenSeq {
  public:
    MemoSeq& this_memo;
    int first;
    size_t len;
    virtual GenSeq *subseq(index_t start, index_t end);
    MemoSubSeq(MemoSeq& m, int f, size_t l) : this_memo(m) {first=f; len = l;}
    virtual Root * index(index_t index);
    virtual size_t length();
    virtual void printBare(ostream& outs) const;
    inline size_t leng() const { return len; }
};

class MemoSeq : public MemoSubSeq {
    DECLARE_MEMBERS(MemoSeq)
  public:
    size_t cur_len;
    size_t allocated;
    Root **buf;
    Functional *rule; // No longer used?
    Function *func;
    MemoSeq *link;
    int _indexed_seqs_count;
    MemoSeq(Functional *, int);
    MemoSeq(Function *, int);
    virtual Root * index(index_t index);
    GenSeq **indexed_seqs() { return (GenSeq**)(this+1); };
    int indexed_seqs_count() { return _indexed_seqs_count; }
#if 0
    virtual int sizeof_file() const;
    virtual void open(GenFile*, OpenFlags flags=0);
#endif
};

class SplayMapFile : public GenFile {
  public:
    const SplayMap *map;
    Pix curIndex;
    SplayMapFile(const SplayMap *m, int flags = 0);
    virtual Root *key();
    virtual Root *next();
    virtual int seek(Root*);
};

class AssignableSplayMap : public AssignableMap {
  public:
    PtrPtrSplayMap map;
    AssignableSplayMap();
    virtual size_t length();
    virtual Root * get(Root *);
    virtual void printon(ostream&) const;
    void put(Root* arg, Root* val);
    virtual Root *value();
};

#if 0
class AMap : public GenMap, public Mapping {
 public:
    MapFile *mapopen(long flags=0) const;
//    virtual GenFile * open(long flags=0) const { return (GenFile*)mapopen(flags); }
};
#endif

struct Mapping {
    struct HashTable h;
    short stride;
    void *argBuf;
    void *valBuf;
    struct Type *argType;
    struct Type *valType;
    int size;
    int bufLength;
    struct Mapping *link; /* Mapping that have been unified */
    struct Any (*rule)(struct Mapping *self, struct Any index);
    struct ProcExpr *expr;
    /* ... environment for rule ... */
};
#endif /*!MAPPING_H*/
