//=-- ConfigFileSection.h - Class for managing sections in config files ------=
//
//  This class is used to keep track of one section (one output page) of the
//  Configuration file.
//
//=---------------------------------------------------------------------------=
//  This file is copyright (c) 1997-1999 Chris Lattner
//=---------------------------------------------------------------------------=

#ifndef CONFIGFILESECTION_H             // Only include this file once
#define CONFIGFILESECTION_H

#include "MSString.h"
#include "MSFilename.h"
#include "Table.h"
#include "VarTable.h"

#include <iostream.h>         // Uses the IOStream libraries...

// SectionLink class - This class is used to keep track of one section of a 
//   configuration file.
// 
class MSAPI CFileSection : public Object {
private :                           // SectionLink's private parts...
  MSFilename CWD;                   // Current Directory when this was created.
  String SectionName;               // The section name.
  VarTable Statements;              // The list of keys.
  VarTable Variables;               // The list of active variables

public :
  // Create a new section.
  CFileSection(const String &sectionName,
               const VarTable &vars, const VarTable &stmts,
               const MSFilename &cwd) 
               : CWD(cwd), SectionName(sectionName), 
                 Statements(stmts), Variables(vars) { }

  CFileSection(const CFileSection &From) : Object(From), 
                               CWD(From.CWD), SectionName(From.SectionName) {
    VarTable::Iterator I = From.Variables.GetStart();
    while (I) {
      Variables[I.GetKey()] = I.GetValue()->AddRef();
      I++;
    }

    VarTable::Iterator J = From.Statements.GetStart();
    while (J) {
      Statements[J.GetKey()] = J.GetValue()->AddRef();
      J++;
    }
  }

  ~CFileSection() {
    VarTable::Iterator I = Variables.GetStart();
    VTExp *New = 0;
    while (I) {
      I.GetValue()->UnRef();
      I.SetValue(New);
      I++;
    }

    VarTable::Iterator J = Statements.GetStart();
    while (J) {
      J.GetValue()->UnRef();
      J.SetValue(New);
      J++;
    }
  }

  // Public access methods
  inline VarTable &GetVariables()  { return Variables;  }
  inline VarTable &GetStatements() { return Statements; } 

  inline const VarTable &GetVariables()  const { return Variables;  }
  inline const VarTable &GetStatements() const { return Statements; } 

  inline const String &GetSectionName()          { return SectionName; }
  inline const MSFilename &GetCWD() const        { return CWD;         }

  int Compare(const Object &S) const { 
    return (SectionName.Compare(((CFileSection&)S).SectionName));
  }

  ostream &print(ostream &s) const {     // Print a link out
    s << '[' << SectionName << ']' << endl;

    VarTable::Iterator I = Variables.GetStart();
    while (I) {
      s << I.GetKey() << " : " << I.GetValue() << ";\n";
      I++;
    }

    VarTable::Iterator J = Statements.GetStart();
    while (J) {
      s << J.GetKey() << " : " << J.GetValue() << ";\n";
      J++;
    }

    return s;
  }
};

#endif
