// configitem.h: interface for the ConfigItem and ConfigItemWrapper class.
//
//////////////////////////////////////////////////////////////////////

#ifndef CONFIGITEM_H
#define CONFIGITEM_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "types.h"
#include "const.h"
#include "osutils.h"

#define NUM_PARMS 20 // maximum number of parameters associated with a descriptor

/*-----------------------------------------------------------------------
CLASS
	ConfigItem

FILE
	configitem.h

DESCRIPTION	
	ConfigItem is an object that contains an ASCII text desription
	and an ASCII data description associated with that text description.
	Data can be read with the parameter() and name() methods of ConfigItem.
	ConfigItem is intended to be used with the ConfigFileManager class
	to contain read and parsed data in a class. ConfigItem can store
	up to 10 items per description. 

HOW TO:
	HOW TO: FORMAT A CONFIG ITEM

	Items must be in the format:

	<Description> <Data>,<Data>,<Data>,<Data>,<Data>

	Each config item must be on separate lines delineated by a 
	carriage return (ASCII 0x0d) or a line feed (ASCII 0x0a).
	
	Some examples:

	NEXT.SAMPLE.TIME	12:00:00
	SYRINGE.MOTOR.PARMS	378,34,3049,8192,8192,2000
	SERIAL.COMM.PARMS	9600,0,1,8

AUTHOR
	Danelle Cline. Copyright 1998 MBARI.			
LOG:
	Modifier 	Date    		Change
	--------   	----    		--------
	D. Cline	10/05/98		Charlie prototype

-----------------------------------------------------------------------*/
class  ConfigItem 
{
public:
	//Default constructor, required for STL
	ConfigItem(const ConfigItem& i)
		:_name(0),_nitems(0){
		memset(_parameter, NULL, sizeof(_parameter));
		_nitems = i.nitems();
		_name = strdup(i.name());
		for(Nat16 j=0; j< i.nitems(); j++)		
			_parameter[j] = strdup(i.parm(j));
	};
	ConfigItem(const char *name, Nat16 nargs, const char **parameters)
		:_name(0),_nitems(0){
		memset(_parameter,NULL, sizeof(_parameter));
		_nitems = min((int)nargs, NUM_PARMS);
		_name = strdup(name);
		for(Nat16 j=0; j< _nitems; j++)			
			_parameter[j] = strdup(parameters[j]);
	};
	~ConfigItem(){
		if(_name != NULL)
			free((void *) _name);				
		for(Nat16 j=0; j< NUM_PARMS; j++)
			if(_parameter[j] != NULL)
				free((void *) _parameter[j]);	
	};
	void replace(Nat16 i, const char *parameter){
		if(i < _nitems && parameter != NULL){
			if(_parameter[i] != NULL){
				free((void *)_parameter[i]);
				_parameter[i] = strdup(parameter);			
			}
		}
	};
	ConfigItem * clone() const { return new ConfigItem (*this);}	
	const char *parm(Nat16 i) const {return _parameter[i];}
	const char *name() const {return _name;}
	Nat16 nitems() const {return _nitems;};
private:	
	const char *_name;
	const char *_parameter[NUM_PARMS];
	Nat16 _nitems;
};

/*-----------------------------------------------------------------------
CLASS
	ConfigItemWrapper

FILE
	configitem.h

DESCRIPTION	
	ConfigItemWrapper wraps a ConfigItem object.
	ConfigItemWrapper is intended to be used with the ConfigFileManager class
	to iterate through individual ConfigItems in 
	ConfigFileManager::searchConfigItems().

AUTHOR
	Danelle Cline. Copyright 1998 MBARI.			
LOG:
	Modifier 	Date    		Change
	--------   	----    		--------
	D. Cline	10/05/98		Charlie prototype

-----------------------------------------------------------------------*/
class ConfigItemWrapper
{
public:
	ConfigItemWrapper(ConfigItem* baseptr = 0) : _pBase(0) {
	_pBase = baseptr;
	}
    ConfigItemWrapper(const ConfigItemWrapper& bw) {		
        _pBase =  bw() ? bw()->clone() : 0;
    }
    ~ConfigItemWrapper() {
		if(_pBase != 0) 
			delete _pBase; 
	}
    const ConfigItem* operator()()  const { return _pBase; }
    ConfigItem* operator()()  { return _pBase; }
	ConfigItemWrapper& operator= (const ConfigItemWrapper& bw) {        
		if(_pBase != 0) delete _pBase;
        if(bw() != 0) _pBase = bw()->clone();		
		return *this;
    };
private:
	ConfigItem* _pBase;
};

#endif //CONFIGITEM_H