package nxm.sys.inc;

import nxm.sys.lib.FileName;
import nxm.sys.lib.Table;

/** A read-only file with record-based data.

    @author  J. Czechowski IV
    @since   NeXtMidas 2.5.4
 */
interface RecordFile {
  /** Get the file name of the file.
      @return The file name as a URL.
   */
  String getURL (); // move?

  /** Get the file name for the file, with any qualifiers and trimmers.
      @return The file name, or null if not set yet.
   */
  FileName getName (); // move?

  /** Open a data connection with specified flags. If the file name is blank and the
      {@link nxm.sys.lib.BaseFile#OPTIONAL} flag is specified.
      @param flags The flags to use (see {@link nxm.sys.lib.BaseFile} for a list of available "I/O
                   open flags."
      @return true if the file is now open, false if unable to open the file (with
              {@link nxm.sys.lib.BaseFile#NOABORT} or  {@link nxm.sys.lib.BaseFile#OPTIONAL}).
      @throws RuntimeException If unable to open the file and NOT using
              {@link nxm.sys.lib.BaseFile#NOABORT} or  {@link nxm.sys.lib.BaseFile#OPTIONAL}.
   */
  boolean open (int flags); // move?

  /** Tells if the file is open.
      @return true if the file is open, false otherwise.
   */
  boolean isOpen (); // move?

  /** Close a data connection. This method should do nothing in cases where the file is not open
      (this permits a primitive to call <code>close()</code> on *any* file without checking to see if
      it is open).
   */
  void close (); // move?

  /** Get the number of rows in the file.
      @return number of rows in the file.
   */
  double getNumberOfRows ();

  /** Indicates if the file is marked as write-protected.
   *  @return true if protected, false if not
   */
  boolean getProtected ();

  /** Get a {@link Table} of data from the file. This will be a table
      <code>{COL1=VAL1,COL2=VAL2,...,COLn=VALn}</code> where <code>COLx</code> is the name of
      the column (which matches {@link #getRecordDef(int)}) and <code>VALx</code> is the associated
      value.<br>
      <br>
      If the given offset is beyond the end of the file, null will be returned. In the extremely
      rare case that the file ends with a partial record, and an attempt is made to read that
      partial record, this method will return null indicating that the end of file was reached
      before the requested data could be read. <br>
      <br>
      Note that providing an offset less than 0 will result in a null being returned.
      @param offset The offset (0 to n-1) into the file. This must be an integral value (the input
                    is a double rather than a long is done for historical reasons).
      @return The data at the given offset or null if at end of the file.
   */
  Table getDataTable (double offset);

  /** Gets the number of record definitions for the file.
   *  @return number of record definitions for the file.
   */
  int getRecordDefCount ();

  /** Gets all of the record/column definitions for the file. Since NeXtMidas 2.5.0, this table is
      indexed by the name of the column, for example:
      <pre>
        {ABSC={NAME="ABSC",FORMAT="SF",OFFSET=I:0,TYPE="UNDEFINED",UNITS="NONE"},
         ORD={NAME="ORD",FORMAT="SF",OFFSET=I:4,TYPE="UNDEFINED",UNITS="NONE"},
         ORD2={NAME="ORD2",FORMAT="SF",OFFSET=I:8,TYPE="UNDEFINED",UNITS="NONE"},
         ORD3={NAME="ORD3",FORMAT="SF",OFFSET=I:12,TYPE="UNDEFINED",UNITS="NONE"}}
      </pre>
      Prior to NeXtMidas 2.5.0, some implementations of {@link ListFile} indexed this table
      numerically 0..N (where n is the FrameSize-1).
      @return record/column definitions for the file.
   */
  Table getRecordDefs ();

  /** Gets the record/column definitions for the file. Each table will have the following fields:
      <pre>
        NAME   - The name of the record.                   (Required)
        FORMAT - The record format.                        (Optional, defaults to string)
        OFFSET - Record byte offset (Blue Type 3000 only). (Optional, not used at this time)
        TYPE   - Computation type (Blue Type 5000 only).   (Optional, defaults to NONE)
        UNITS  - Data units (see {@link Units}).                   (Optional, defaults to NONE)
      </pre>
      @param i The index of the definition (0..n).
      @return The record definition.
   */
  Table getRecordDef (int i);
}
