/*
 *  menustr.h from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, 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.
 */
/*  menustr.h   */
/*  Copyright 1991 Mountain Math Software  */
/*  All Rights Reserved                    */
#ifndef MENUSTR_DOT_H
#define MENUSTR_DOT_H
#include "mentyp.h"
#include "slist.h"
#include "portable.h"

class ostream ;
class OutTokens ;
struct InitValue ;
class MenuItemList ;
class TeXPrintDesc ;
class ObjectDescript ;
class MenuItem ;
class ClassRelation ;

struct MenuDef {
	const char * Name;
	InitValue * Init ;
	const char * Title ;
	MenuItemList * Items ;
	MenuType Type ;
	const ObjectDescript * MenuObject ;
	const ClassRelation * TheClassRelation;	// 0 if not in class tree
	MenuDef(const char * name, InitValue * init, const char * title,
		MenuItemList * items, MenuType type);

	const char * GetName() const {return Name;}

	int IsDynamicMenu() const {return Type.IsDynamic();}
	int IsOrphan() const {return Type.IsOrphan();}
	void TeXPrint(TeXPrintDesc& Out) const ;
	void TeXPicture(TeXPrintDesc& Out) const ;
	int IsThisMenu(const char * Name) const ;
	void PrintAllTeXMenus(ostream& out) const ;
	void TeXSectionHeader(TeXPrintDesc& Out) const ;
	const ObjectDescript * SetMenuObject(const ObjectDescript * obj)
		{return MenuObject = obj;}
	const ObjectDescript * GetObject() const {return MenuObject;}
	const char * GetRef() const ;
	void SetIsOutput() const ;
	// This illegally sets the output flag in const member MemberObject
	int IsOutput() const ;
	void PrintChildren(TeXPrintDesc& Out) const ;
	void PrintChildrenSections(TeXPrintDesc& Out) const ;
	const char * GetMenuCommand() const ;
	const MenuDef * GetParent() const ;
	const MenuItem * GetParentItem() const ;
	const MenuItem * GetThisItem(const char * Name) const;
	void MainMenuHelp(TeXPrintDesc& Out) const ;
	int IsMainMenu() const ;

	void SetChildrenPrintDynamic(int AvoidRecursion=1) const ;
	void SetDoNotPrint();

	int IsPrintDynamic() const ;
	int IsPrinted() const ;
	int IsDoNotPrint() const ;
	int IsTemplate() const ;

	const ClassRelation * GetClassRelation() const{return TheClassRelation;}
	void OutRef(OutTokens& Out) const ;

	int IsMemberFunctionSelector() const ;
	int IsMemberFunctionExecSelector() const ;

	void PrintAllOrphanedMenus(TeXPrintDesc& OutDesc) const ;
	void OrphanSectionHead(TeXPrintDesc& Out) const ;

	void OrphanExecOut(OutTokens& Out) const ;
	void OrphanOut(OutTokens& Out) const ; 
};
	
class MenuDefList: public SingleList {
public:
	ErrCode Insert(MenuDef *nt) {return SingleList::Insert(nt);}
	ErrCode Append(MenuDef  *nt) {return SingleList::Append(nt);}
	MenuDef  * Get()   {return (MenuDef  *) SingleList::Get();}
	MenuDefList(){;}
	int Size(){return SingleList::Size();}
	void TeXPrint(ostream& Out) ;
	const MenuDef * FindParentMenu(const char * child);
	const MenuDef * FindMenu(const char * Name);
} ;


struct Compound ;
class TextFragmentList ;

class MenuItem {
	const char * Command ;
	struct ParameterizedAction * Action ;
	int ActionType ;
	struct ParameterizedAction * Init ;
	int InitActionType ;
	const char * MenuString ;		// Menu prompt
	const char * MenuHelpReference ;	// Name of previous defined
						// 	help text
	struct HelpText * MenuHelp ;		// Help text
	const char * HelpFileName ;		// Help file name
	MenuType ParentType ;
	const ObjectDescript * CommandObject ;
	const ClassRelation * TheClassRelation;	// 0 if not in class tree
public :
	MenuItem(const char * cmd, ParameterizedAction * act, int typ,
		ParameterizedAction * init, int InitAct, const char * MenStr,
		const char * help_ref,
		HelpText * help, const char * help_name);
	MenuItem(MenuItem& ) ;
	void SetParentType(MenuType parent) {ParentType = parent;}
	MenuType GetParentType() {return ParentType;}
	int IsHistory() {return GetParentType().IsHistory();}
	const char * GetCommand() const {return Command;}
	ParameterizedAction * GetAction() const {return Action;}
	int GetActionType()	const {return ActionType;}
	ParameterizedAction * GetInit()	{return Init;}
	int GetInitAction()	const {return InitActionType;}
	const char * GetMenuString() const {return MenuString;}
	const char * GetMenuHelpReference() const {return MenuHelpReference;}
	HelpText * GetMenuHelp() const {return MenuHelp;}
	const char * GetHelpFileName() const {return HelpFileName;}
	void Dump(const char *);

	const char * GetRefName() const ;
	int IsMenu() const ;
	void TeXPrint(TeXPrintDesc& Out);
	const ObjectDescript * SetCommandObject(const ObjectDescript * obj)
		{return CommandObject = obj;}
	const ObjectDescript * GetObject() const {return CommandObject;}
	const char * GetRef() const ;

	void SetIsOutput() const ;
	// This illegally sets the output flag in const member CommandObject
	int IsOutput() const ;

	void TeXCommandType(TeXPrintDesc& Out) const ;
	void TeXPrintInParentSection(TeXPrintDesc& Out) const ;
	void TeXPrintSection(TeXPrintDesc& Out) const ;
	void TeXPrintCommand(OutTokens& Out) const ;
	const char * GetParentRef() const ;
	const char * GetChildRef() const ;
	int ChildIsEmpty() const ; 		// 0 if not a menu
	const MenuDef * GetChildMenu() const ;	// NULL if not a menu
	const MenuDef * GetParent() const ;
	void SetChildrenPrintDynamic() const ;
	void SetChildrenDoNotPrint() const ;
	int IsChildMenuPrintedInFull() const ;
	int IsChildMenuMentioned() const ;

	void OutputBaseMemberRefExec(TeXPrintDesc& Out) const ;
	void OutputBaseMemberRef(TeXPrintDesc& Out) const ;

	int IsMemberFunctionSelector() const ;
	int IsMemberFunctionExecSelector() const ;

	void CheckForBaseClassReference(TeXPrintDesc& Out) const  ;
	const ClassRelation * GetClassRelation() const{return TheClassRelation;}

} ;
	

class MenuItemList: public SingleList {
public:
	ErrCode Insert(MenuItem *nt) {return SingleList::Insert(nt);}
	ErrCode Append(MenuItem  *nt) {return SingleList::Append(nt);}
	MenuItem  * Get()   {return (MenuItem  *) SingleList::Get();}
	MenuItemList(){;}
	int Size(){return SingleList::Size();}
	void Dump(const char * Where) ;
	const MenuItem * FindMenu(const char * Name) ;
	const MenuItem * FindItem(const char * Name) ;
	void TeXPrint(TeXPrintDesc& Out) ;
} ;



class MenuItemListIterator: public SingleListIterator {
public:
	MenuItemListIterator(MenuItemList& df):
		SingleListIterator((SingleList&) df){}
	MenuItem * operator()()
		{return (MenuItem *) Next();}
};




class MenuDefListIterator: public SingleListIterator {
public:
	MenuDefListIterator(MenuDefList& df):
		SingleListIterator((SingleList&) df){}
	MenuDef * operator()()
		{return (MenuDef *) Next();}
};

struct MainEntryPair {
	const char * AllMenus ;
	const char * MenuName ;
	int Found ;
	MainEntryPair(const char * All,const char * Name)
		{AllMenus =All; MenuName=Name; Found=0;}
	const char * ThisClass(const char * ClassName) const ;
} ;

class MainEntryList: public SingleList {
public:
	ErrCode Insert(MainEntryPair *nt) {return SingleList::Insert(nt);}
	ErrCode Append(MainEntryPair  *nt) {return SingleList::Append(nt);}
	MainEntryPair  * Get()   {return (MainEntryPair  *) SingleList::Get();}
	MainEntryList(){;}
	int Size(){return SingleList::Size();}
	void Dump(const char * Where) ;
	const char * FindMainMenu(const char * MenuType) ;
} ;


class MainEntryListIterator: public SingleListIterator {
public:
	MainEntryListIterator(MainEntryList& df):
		SingleListIterator((SingleList&) df){}
	MainEntryPair * operator()()
		{return (MainEntryPair *) Next();}
};

struct HelpText {
	const char * Name ;
	const char ** Text ;
	const char **TeXText ;
	HelpText(const char * name, const char ** text, const char ** tex_t)
		{ Name = name; Text = text;TeXText=tex_t;}
	~HelpText() {}
	void TeXOut(OutTokens& Out) const ;
};

class TextList: public SingleList {
public:
	ErrCode Insert(HelpText * nt)
		{return SingleList::Insert((HelpText *) nt);}
	ErrCode Append(HelpText * nt)
		{return SingleList::Append((HelpText *) nt);}
	HelpText * Get()   {return (HelpText *) SingleList::Get();}
	TextList(){;}
	int Size(){return SingleList::Size();}
} ;



class TextListIterator: public SingleListIterator {
public:
	TextListIterator(TextList& df):
		SingleListIterator((SingleList&) df){}
	HelpText * operator()()
		{return (HelpText *) Next();}
};


extern MenuDefList TheMenuDefs ;
extern MenuDefList TheOrphans ;

extern MainEntryList MainEntrys ;


#endif /* #ifdef MENUSTR_DOT_H */
