//
// This file is part of the SDTS++ toolkit, written by the U.S.
// Geological Survey.  It is experimental software, written to support
// USGS research and cartographic data production.
// 
// SDTS++ is public domain software.  It may be freely copied,
// distributed, and modified.  The USGS welcomes user feedback, but makes
// no committment to any level of support for this code.  See the SDTS
// web site at http://mcmcweb.er.usgs.gov/sdts for more information,
// including points of contact.
//
// $Id: sb_Catd.h,v 1.7 2000/07/25 20:05:38 mcoletti Exp $
//
#ifndef INCLUDED_SB_CATD_H
#define INCLUDED_SB_CATD_H

#include <list>

#include <string>

#ifndef SB_MODULE_H
#include <sdts++/builder/sb_Module.h>
#endif


#ifndef INCLUDED_SIO8211FIELDFORMAT_H
#include <sdts++/io/sio_8211FieldFormat.h>
#endif

class  sb_ForeignID;
class  sc_Record;


///
struct sb_Catd_Imp;


/**
 This class provides a convenient access to CATD records.  It provides
 members to access or set various module field and subfield values.
 It also provides a mechanism for populating an object of this class with
 values found in a valid sc_Record of this module, and for filling a
 sc_Record with the contents of a sb_Catd object.
*/
class sb_Catd : public sb_Module
{
   public:

      sb_Catd();

      ~sb_Catd();


      /**
       Use these members to get subfield/field values.  Pass in an appropriate
       type to receive the value.  These members will return false if the 
       corresponding value is not set.  (It may not be set because a value 
       was not assigned to it, or because you previously tried to assign 
       an invalid value.)  Otherwise they will return true.
      */
      bool getName( string& val ) const;

      /// /sa getName( string& val )
      bool getNAME( string& val ) const { return getName( val ); }

      /// /sa getName( string& val )
      bool getType( string& val ) const;
      /// /sa getName( string& val )
      bool getTYPE( string& val ) const { return getType( val ); }

      /// /sa getName( string& val )
      bool getVolume( string& val ) const;
      /// /sa getName( string& val )
      bool getVOLM( string& val ) const { return getVolume( val ); }

      /// /sa getName( string& val )
      bool getFile( string& val ) const;
      /// /sa getName( string& val )
      bool getFILE( string& val ) const { return getFile( val ); }


#ifdef NOT_SUPPORTED
      bool getRecord( string& val ) const;
      bool getRECD( string& val ) const { return getRecord( val ); }
#endif

      /// /sa getName( string& val )
      bool getExternal( string& val ) const;
      /// /sa getName( string& val )
      bool getEXTR( string& val ) const { return getExternal( val ); }

      /// /sa getName( string& val )
      bool getModuleVersion( string& val ) const;
      /// /sa getName( string& val )
      bool getMVER( string& val ) const { return getModuleVersion( val ); }

      /// /sa getName( string& val )
      bool getComment( string& val ) const;
      /// /sa getName( string& val )
      bool getCOMT( string& val ) const { return getComment( val ); }


      /**
         fill the given record based on the builder's object
       field/subfield values -- return false if in a wedged
       state. (E.g., a mandatory field isn't set or was assigned a
       value outside its proper domain.
      */
      bool getRecord( sc_Record& val ) const;


      /**
       set the object with values found in the record; if not a valid
       CATD record, this will return false
      */
      bool setRecord( sc_Record const& val );


      /**
       Use these members to set subfield/field values.  Pass in an appropriate
       value for the particular subfield/field to be set to.  They will return
       false if you try to assign a value outside the domain of the given 
       subfield/field.  (Note that this is not too pedantic; for example, we
       do not check to see if a conditionally mandatory or optional field has
       been set.)
      */
      bool setName( string const& val );
      /// /sa setName( string const& val )
      bool setNAME( string const& val ) { return setName( val ); }

      /// /sa setName( string const& val )
      bool setType( string const& val );
      /// /sa setName( string const& val )
      bool setTYPE( string const& val ) { return setType( val ); }

      /// /sa setName( string const& val )
      bool setVolume( string const& val );
      /// /sa setName( string const& val )
      bool setVOLM( string const& val ) { return setVolume( val ); }

      /// /sa setName( string const& val )
      bool setFile( string const& val );
      /// /sa setName( string const& val )
      bool setFILE( string const& val ) { return setFile( val ); }

#ifdef NOT_SUPPORTED
      bool setRecord( string const& val );
      bool setRECD( string const& val ) { return setRecord( val ); }
#endif

      /// /sa setName( string const& val )
      bool setExternal( string const& val );
      /// /sa setName( string const& val )
      bool setEXTR( string const& val ) { return setExternal( val ); }

      /// /sa setName( string const& val )
      bool setModuleVersion( string const& val );
      /// /sa setName( string const& val )
      bool setMVER( string const& val ) { return setModuleVersion( val ); }

      /// /sa setName( string const& val )
      bool setComment( string const& val );
      /// /sa setName( string const& val )
      bool setCOMT( string const& val ) { return setComment( val ); }


      /**
       Since builder objects will be frequently 'recycled' (i.e., used for
       more than one record), it might be convenient to 'unset' a previously
       assigned value.  So:
      */
      void unDefineName( );
      // /sa void unDefineName( )
      void unDefineNAME( ) { unDefineName( ); }

      // /sa void unDefineName( )
      void unDefineType( );
      // /sa void unDefineName( )
      void unDefineTYPE( ) { unDefineType( ); }

      // /sa void unDefineName( )
      void unDefineVolume( );
      // /sa void unDefineName( )
      void unDefineVOLM( ) { unDefineVolume( ); }

      // /sa void unDefineName( )
      void unDefineFile( );
      // /sa void unDefineName( )
      void unDefineFILE( ) { unDefineFile( ); }

#ifdef NOT_SUPPORTED
      void unDefineRecord( );
      void unDefineRECD( ) { unDefineRecord( ); }
#endif

      // /sa void unDefineName( )
      void unDefineExternal( );
      // /sa void unDefineName( )
      void unDefineEXTR( ) { unDefineExternal( ); }

      // /sa void unDefineName( )
      void unDefineModuleVersion( );
      // /sa void unDefineName( )
      void unDefineMVER( ) { unDefineModuleVersion( ); }

      // /sa void unDefineName( )
      void unDefineComment( );
      // /sa void unDefineName( )
      void unDefineCOMT( ) { unDefineComment( ); }


   private:

      /// returns reference to schema
      sio_8211Schema& schema_();

      /// used to create internal schema
      void buildSpecificSchema_();


      /// NOT NEEDED
      sb_Catd(sb_Catd const& right);

      /// NOT NEEDED
      sb_Catd const& operator=(sb_Catd const& right);

      /// pointer to opaque data structure
      sb_Catd_Imp* imp_;

}; // sb_Catd


#endif // INCLUDED_SB_CATD_H

