/*
 *  playback.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.
 */
#ifndef PLAYBACK_DOT_H
#define PLAYBACK_DOT_H
#include "dsp_app.h"
#include "slist.h"
#include "mkstr.h"
#include "errcode.h"

class MenuKeyboard ;
class FocusSelector ;
class ifstream ;

class IndexedName {
	const char * base ;
	int index ;
public:
	IndexedName(const char * name):base(name),index(0){}
	const char * base_name() const {return base;}
	char * new_version() ;
};

class IndexedNameList : public SingleList {
public:
	ErrCode insert(IndexedName *nt) {return SingleList::Insert(nt);}
	ErrCode append(IndexedName *nt) {return SingleList::Append(nt);}
	IndexedName * Get() {return (IndexedName *) SingleList::Get();}
	IndexedName * Pop() {return (IndexedName *) SingleList::Pop();}
	IndexedNameList(){;}
	int Size(){return SingleList::Size();}
	char * is_new_name(const char * name);
		// returns name to be deleted by caller 
} ;

class IndexedNameListIterator:public SingleListIterator {
public:
	IndexedNameListIterator(IndexedNameList& df):
		SingleListIterator((SingleList&) df) {}
	IndexedName * operator()() {return (IndexedName *) Next();}
};


class WindowOrKeyboard {
	FocusSelector * the_window ;
	MenuKeyboard * the_keyboard ;
	char * the_name ;
	static IndexedNameList the_names ;
	void make_name();
public:
	WindowOrKeyboard(FocusSelector *win);
	~WindowOrKeyboard();
	WindowOrKeyboard(MenuKeyboard *key);
	FocusSelector * window() const {return the_window;}
	MenuKeyboard * keyboard() const {return the_keyboard;}
	const char * name() const{return the_name;}
	void set(FocusSelector * sel){the_window=sel;}
};
	

class WindowOrKeyboardList : public SingleList {
	const char * main_window_prefix ;
	const char * info_window_name ;
	int length ;
	int warn_check ;
public:
	WindowOrKeyboardList(const char * name_main_prefix, const char * name_info);
	ErrCode insert(WindowOrKeyboard *nt) {return SingleList::Insert(nt);}
	ErrCode append(WindowOrKeyboard *nt) {return SingleList::Append(nt);}
	WindowOrKeyboard * Get()
		{return (WindowOrKeyboard *) SingleList::Get();}
	WindowOrKeyboard * Pop()
		{return (WindowOrKeyboard *) SingleList::Pop();}
	WindowOrKeyboardList(){;}
	int Size(){return SingleList::Size();}
	WindowOrKeyboard * find(const char * name);
	MenuKeyboard * find_keyboard(const char * name);
	ErrCode remove(WindowOrKeyboard * k)
		{return SingleList::RemoveEntry(k);}
	void new_file() {warn_check=0;}
	const char * add(MenuKeyboard *key);
	const char * add(FocusSelector *win);
	const char * add(WindowOrKeyboard * obj);
	void remove(const char * name);
	void remove(FocusSelector * win);
	void remove(MenuKeyboard * key);
} ;

class WindowOrKeyboardListIterator:public SingleListIterator {
public:
	WindowOrKeyboardListIterator(WindowOrKeyboardList& df):SingleListIterator((SingleList&) df)
		{}
	WindowOrKeyboard * operator()() {return (WindowOrKeyboard *) Next();}
};

class File {
	ifstream * the_file ;
	int32 the_line ;
	char * the_name ;
public:
	File(const char * name);
	~File();
	int good() {return the_file != 0;}
	int32 line() {return the_line;}
	ifstream & file() {return *the_file;}
	const char * name() {return the_name;}

	void yyerror(const char* s1,const char* s2=0, const char* s3=0,
		const char* s4=0, const char*s5=0) ;
	void error_at();
	int mygetc();
	void new_line() {the_line++;}
	void log_current_line();
};

class FileList : public SingleList {
public:
	ErrCode insert(File *nt) {return SingleList::Insert(nt);}
	ErrCode append(File *nt) ;
	File * get()   {return (File *) SingleList::Get();}
	File * pop() {return (File *) SingleList::Pop();}
	FileList(){;}
	int size(){return SingleList::Size();}
	void clear() ;
	ErrCode remove(File * k)
		{return SingleList::RemoveEntry(k);}
} ;

class FileListIterator:public SingleListIterator {
public:
	FileListIterator(FileList& df):SingleListIterator((SingleList&) df)
		{}
	File * operator()() {return (File *) Next();}
};

struct DeferredAct {
	int32 act ;
	const char * window ;
	const char * select ;
	const char * prompt ;
	void init() {window=select=prompt=0;act=-1;}
	void dump();
};


class ManagedKeyboards {
	static WindowOrKeyboardList the_managed_keyboards ;
	static ManagedKeyboards the_manager ;
	FileList the_file_list ;
	File * the_active_file ;
	int file_state ;
	int continue_after_error ;
	int last_char ;
	int yywrap_called ;
	int abort_flag ;
	int delay ;
	char * delay_err_msg ;
	DeferredAct deferred_act ;
	int action_recorded ;
	char ** menu_history ;

	void do_deferred();
	void do_deferred_act();
	void do_deferred_prompt();
	void do_deferred_text();
	void defer_act(int32 action, const char * select, const char * window);
	void defer_prompt(const char * string);
public:
	ManagedKeyboards();
	static const char * add(MenuKeyboard * key);
	static const char * add(FocusSelector *win);
	static void remove(const char * name);
	static void remove(MenuKeyboard * key);
	static void remove(FocusSelector *win);
	static WindowOrKeyboard * find(const char * name);
	ivWindow * find_window(const char * name);
	FocusSelector * find_focus(const char * name);
	void playback(const char * file_name);
	static ManagedKeyboards * manager();
	void set_action_recorded(){action_recorded = 1 ;}
	void clear_action_recorded() {action_recorded = 0 ;}
	int is_action_recorded() const {return action_recorded;}

	void do_act(int32 action, const char * select, const char * window);
	void action(int32 type, int32 action, const char * select,
		const char * window);
	void prompt(const char * string);
	void menu_text(const char * test);
	void dpp_text(const char * test);
	void new_line();
	void illegal(char c);
	int mygetc();
	int yywrap();

	int read_line(); // returns 1 if successfull
	int parse_execute(); // returns 0 if successfull

	void yyerror(const char* s1,const char* s2=0, const char* s3=0,
		const char* s4=0, const char*s5=0) ;

	void play_actions();
	void play_pause();
	void pause_call_back(const char * str);
	void abort_play();
	void record_actions(const char * file_name=0);
	void record_off();
	void record_flush();

	void error_callback(const char * msg);
	File * active_file() const {return the_active_file;}
	void check_wait_for_dsp() ;
	void start_menu_state();
	void ManagedKeyboards::record_menu_state();
	void add_to_menu_state(char * str);
	static const int max_menu_history ;
	const char ** const menu_history_array() {return menu_history;}
	void log_current_line();
};
#endif /* #ifdef PLAYBACK_DOT_H */
