// ---------------------------------------------------------------------------
// - Table.hpp                                                               -
// - aleph:odb library - table class definition                              -
// ---------------------------------------------------------------------------
// - This program is free software;  you can rodbstribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2003 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef  ALEPH_TABLE_HPP
#define  ALEPH_TABLE_HPP

#ifndef  ALEPH_STRVEC_HPP
#include "Strvec.hpp"
#endif

#ifndef  ALEPH_RECORD_HPP
#include "Record.hpp"
#endif

namespace aleph {

  /// The Table class is a collection of records. Because of the record
  /// format, a table look like a 2-dimensional array of cells. Like the
  /// record, the table is defined with a name and a vector of records.
  /// @author amaury darsch

  class Table : public Persist {
  private:
    /// the table name
    long   d_quark;
    /// the record info
    Record  d_info;
    /// the record header
    Record  d_head;
    /// the record footer
    Record  d_foot;
    /// the keys vectors
    Strvec  d_keys;
    /// the record vector
    Vector  d_vrcds;
    
  public:
    /// create an empty table
    Table (void);

    /// create a new table with a name
    /// @param name the table name
    Table (const String& name);

    /// @return the object name
    String repr (void) const;

    /// @return the format serial id
    t_byte serialid (void) const;

    /// serialize this table
    /// @param os the output stream
    void wrstream (Output& os) const;

    /// deserialize this table
    /// @param is the input stream
    void rdstream (Input& os);

    /// import data in the table
    /// @param is the input stream
    void import (Input* is);

    /// export a table into an output stream
    /// @param os the output stream to write
    /// @param max the maximum number of rows
    /// @param start the row start index
    /// @param flag  the use string or literal represenntation
    void report (Output& os, long max, long start, bool flag) const;

    /// @return the table name
    String getname (void) const;

    /// set the table name
    /// @param name the name to set
    void setname (const String& name);

    /// add a new literal in the descriptor
    /// @param lobj the literal to add
    void addinfo (Literal* lobj);

    /// @return an info cell by index
    Cell* getinfo (const long index) const;

    /// @return an info cell value by index
    Literal* evalinfo (const long index) const;

    /// set a literal in the info descriptor by index
    /// @param index the info index to set
    /// @param lobj  the literal to set
    void setinfo (const long index, Literal* lobj);

    /// add a new literal in the header
    /// @param lobj the literal to add
    void addhead (Literal* lobj);

    /// @return a header cell by index
    Cell* gethead (const long index) const;

    /// @return a header cell value by index
    Literal* evalhead (const long index) const;

    /// set a literal in the header by index
    /// @param index the info index to set
    /// @param lobj  the literal to set
    void sethead (const long index, Literal* lobj);

    /// add a new literal in the footer
    /// @param lobj the literal to add
    void addfoot (Literal* lobj);

    /// @return a footer cell by index
    Cell* getfoot (const long index) const;

    /// @return a footer cell value by index
    Literal* evalfoot (const long index) const;

    /// set a literal in the footer by index
    /// @param index the info index to set
    /// @param lobj  the literal to set
    void setfoot (const long index, Literal* lobj);

    /// add a new key in this table
    /// @param key the key to add
    void addkey (const String& key);

    /// @return a key index by name
    long mapkey (const String& key) const;

    /// @return a key name by index
    String getkey (const long index) const;

    /// add a new record in this table
    /// @param rcd the record to add
    void add (Record* rcd);

    /// add a cons list in this table
    /// @param cons the cons list to add
    void add (Cons* cons);

    /// add a vector of literal in this table
    /// @param argv the vector to add
    void add (Vector* argv);

    /// @return a record by index
    Record* get (const long index) const;

    /// set a record in this table by index
    /// @param index the record index
    /// @param rcd   the record to set
    void set (const long index, Record* rcd);

    /// @return the table length
    long length (void) const;

    /// @return the number of columns
    long getcols (void) const;

    /// generate a new table
    /// @param argv the argument vector
    static Object* mknew (Vector* argv);

    /// apply this table with a set of arguments and a quark
    /// @param robj  robj the current runnable
    /// @param nset  the current nameset    
    /// @param quark the quark to apply these arguments
    /// @param argv  the arguments to apply
    Object* apply (Runnable* robj, Nameset* nset, const long quark,
                   Vector* argv);
    
  private:
    // make the copy constructor private
    Table (const Table&);
    // make the assignment operator private
    Table& operator = (const Table&);
  };
}

#endif
