/*
 *  user.h from ObjectProDSP 0.1
 *  Copyright (C) 1994, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  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. See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
#ifndef USER_DOT_H
#define USER_DOT_H
/*  user.h   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include "ObjProDSP/portable.h"
#include "ObjProGen/slist.h"
#include "ObjProDSP/entenm.h"
#include "ObjProGui/basic.h"


// The following is the interface used in fetching parameters
// It must support both interactive interrogation and interface
// to the command (interpretive C++) mode.

class UserParameters ;
struct OneParameter ;

typedef int32 (*IntComputeBound)(CheckAction, struct OneParameter&,
	const struct OneParameter ** List = 0,class OutTokens * Out=0) ;

typedef double (*FloatComputeBound)(CheckAction, struct OneParameter&,
	const struct OneParameter ** List = 0,OutTokens * Out=0) ;

struct DoCheckFloatBound {
	FloatComputeBound GetBound ;
	const struct OneParameter ** List ;
	double Bound(OneParameter& p)
		{return GetBound(CheckActionCheck,p,List);}
} ;
	// Name of routine to check and possibly null list of other parameters
	// that routine expects as second parameter

struct DoCheckIntBound { IntComputeBound GetBound ;
	const struct OneParameter ** List ;
	int32 Bound(OneParameter& p) {return GetBound(CheckActionCheck,p,List);}
} ;
	// Name of routine to check and possibly null list of other parameters
	// that routine expects as second parameter

typedef int (*CheckFunc) (CheckAction, struct OneParameter *,
	const struct OneParameter ** List=0,OutTokens * Out=0) ;

struct DoCheckFunc { CheckFunc DoCheck ; const struct OneParameter ** List; } ;
	// Name of routine to check and possibly null list of other parameters
	// that routine expects as second parameter
	// Depending in CheckAction DoCheck returns
	// a description of what it does
	// or a NULL string

struct IntParam {
	int32 Default ;
	int32 CurrentValue ;
	DoCheckIntBound * CheckLower ;
	int32 Lower ;
	DoCheckIntBound * CheckUpper ;
	int32 Upper ;
	void GetParameter(const char *, OneParameter&,ValueType * Val,int i=0) ;
	int32 GetParameterValue() {return CurrentValue;}
	int32 TheLowerBound(struct OneParameter& p)
		{return CheckLower ? CheckLower->GetBound(CheckActionCheck,p,
			CheckLower->List) : Lower;}
	int32 TheUpperBound(struct OneParameter& p)
		{return CheckUpper ? CheckUpper->GetBound(CheckActionCheck,p,
			CheckUpper->List) : Upper;}
	void List(OneParameter&,OutTokens& Out) ;
	void ListValue(OneParameter&,OutTokens& Out) ;
	int CppList(OutTokens& Out, CppListCmds Cmd) ;
} ;

struct FloatParam {
	double Default ;
	double CurrentValue ;
	DoCheckFloatBound * CheckLower ;
	double Lower ;
	DoCheckFloatBound * CheckUpper ;
	double Upper ;
	void GetParameter(const char *, OneParameter&, ValueType *,int i = 0) ;
	double GetParameterValue() {return CurrentValue;}
	double TheLowerBound(struct OneParameter& p)
		{return CheckLower ? CheckLower->GetBound(CheckActionCheck,p,
			CheckLower->List) : Lower;}
	double TheUpperBound(struct OneParameter& p)
		{return CheckUpper ? CheckUpper->GetBound(CheckActionCheck,p,
			CheckUpper->List) : Upper;}
	void List(OneParameter&,OutTokens& Out) ;
	void ListValue(OneParameter&,OutTokens& Out) ;
	int CppList(OutTokens& Out, CppListCmds Cmd) ;
} ;

typedef const char * (*CheckLegalString)(const char *);

typedef const char * (*DefaultStringMake)(const char *, int32) ;
// If called with a Null string this describes how the the default
// name is modified to create a new string

struct StringParam {
	const char * Default ;
	DefaultStringMake MakeString ;
	const char * CurrentValue ;
	CheckLegalString Legal ;
	void GetDefaultParameter() ;
	void GetParameter(const char *, int32 NextNameIndex,ValueType *,
		int i = 0) ;
	void GetNameParameter(const char *, int32 NextNameIndex,ValueType *) ;
	const char * GetParameterValue() {return CurrentValue;}
	void List(OutTokens& Out,int ) ;
	void ListValue(OutTokens& Out ) ;
	int CppList(OutTokens& Out, CppListCmds Cmd) ;
	void GetDefaultName(InteractiveEntity *);
} ;

typedef const char * (*CheckLegalEntity)(UserEntity *);
typedef const char * (*GetDefaultValue)(UserEntity *);

struct EntityParam {
	const char * DefaultValue ;
	const char * EntityClass ;
	CheckLegalEntity Legal ;
	UserEntity * CurrentValue ;
	GetDefaultValue ComputeDefault ;
	void GetDefaultParameter(UserEntity * TheObject) ;
	UserEntity * GetParameterValue() {return CurrentValue;}
	UserEntity * GetParameter(const char *, OneParameter&,
		ValueType *,int i = 0,UserEntity * TheEntity=0) ;
	void List(OutTokens& Out,int ) ;
	void ListValue(OutTokens& Out ) ;
	int CppListDec(OutTokens& Out, CppListCmds) ;
	int CppList(OutTokens& Out, CppListCmds Cmd) ;
} ;


struct OneParameter {
	const char * Name ;
	DoCheckFunc * Check;
		// If function is not null then this determines
		// based on previous parameter values if this
		// value is needed at all.
	const char * Description ;
	IntParam * IntP ;
	FloatParam * FloatP ;
	StringParam * StringP ;
	EntityParam * EntityP ;
	struct ArrayParam * ArrayP ;
	int FirstDefaultParameter ;
	int GetParameter(int32 NextNameIndex,ValueType*,int i=0,
		UserEntity * TheObject=0) ;
	void GetDefaultParameter(UserEntity * TheObject=0);
	int32 GetIntParameterValue() ;
	double GetFloatParameterValue() ;
	const char * GetStringParameterValue() ;
	UserEntity * GetEntityParameterValue() ;
	void * GetArrayParameterValue();
	int32 GetLengthArrayParameterValue();
	void ListCommon(OutTokens& Out) ;
	void List(OutTokens& Out,int) ;
	void ListValue(OutTokens& Out) ;
	const char * GetTypeName() ;
	int IsScalar();
	int IsNumeric();
	int IsComplex();
	const char * GetName() {return Name;}
	int CppListDec(OutTokens&, CppListCmds, UserEntity *); 
	int CppList(OutTokens& Out, CppListCmds Cmd) ;
	int IsFirstDefault() { return FirstDefaultParameter;}
	void GetDefaultName(InteractiveEntity * ent);
} ;


typedef int (*GlobalCheck) (CheckAction, UserParameters& ) ;
	
class UserParameters {
	OneParameter * Parameters ;
	GlobalCheck Check ;
public:
	UserParameters(OneParameter * Array,
		GlobalCheck ck=0){Parameters=Array;Check=ck;}
	Interrogate();
	int GetParameters(int32 NextNameIndex) ;
	OneParameter * GetOneParameter(const char * Name);
	OneParameter * GetAllParameters() {return Parameters;}
	void GetDefaultParameters(UserEntity * TheObject=0, int i = 1) ;
	int32 GetIntParameterValue(const char * name);
	const char * GetStringParameterValue(const char * name);
	double GetFloatParameterValue(const char * name);
	void * GetArrayParameterValue(const char * name);
	int32 GetLengthArrayParameterValue(const char * name);
	UserEntity * GetEntityParameterValue(const char * name) ;
	void List(OutTokens&,int) ;
	void ListValue(const char * Name, OutTokens&) ;
	void ListValues(OutTokens&) ;
	int SetParamValues(int32 NextNameIndex, ValueType *Vals);
	int CompleteSetParamValues(int i, int DefaultOk, const char * Name,
		int NextNameIndex=0);
	int SetValues(ValueType*) ; 
	int SetValues(int32,ValueType*) ;  // set values and insure
				// correct number type and value of
				// parameters (int32 is for constructors
				// when a name must be created)
	void ClearValues() { }
	int CppListDec(OutTokens&,CppListCmds,UserEntity * ThisObject) ;
	int CppList(OutTokens&,CppListCmds);
	void GetDefaultName(InteractiveEntity *);
} ;

typedef ValueType * (*UserProcedure)(OutTokens&,EntityReq,UserParameters *,
	UserEntity *) ;

class Procedure: public UserEntity {
	UserProcedure Call ;
	UserParameters * TheParameters ;
	const char * TypeName ;
	Procedure * Overload ;
	const char * MenuLine ;
public :
	Procedure(const char * Name, UserProcedure call,
		UserParameters * parameters, const char * type = 0,
		Procedure * Ovld = 0, const char * MenuLine =0) ;
	UserParameters * GetParameters() {return TheParameters;}
	void SetMenuLine(const char * Line) {MenuLine = Line;}
	ValueType * DoCall(OutTokens& Out,EntityReq Req,UserEntity *Ent) ;
	UserProcedure GetCall() {return Call ;}
	void Dump(OutTokens&, class ValueTypeList *);
	int CppList(OutTokens&,CppListCmds);
	void Describe(OutTokens&,ListEntity);
	Procedure * GetOverload() {return Overload;}
	const char * GetMenuLine() {return MenuLine;}
	const char * GetTypeName() ;
} ;

int strobjcmp(const char * str1, const char * str2) ;
int ReturnCheckConvert(ValueType * Source, DecType DestType) ;
InteractiveEntity * GetBaseType(InteractiveEntity * FoundClass,
	const char * DesiredClass) ;


#endif /* #ifdef USER_DOT_H */

