#include <IV-look/kit.h>
#include <InterViews/event.h>
#include <InterViews/action.h>
#include <InterViews/background.h>
#include <InterViews/layout.h>
#include <InterViews/session.h>
#include <InterViews/color.h>
#include <InterViews/border.h>
#include <InterViews/style.h>
#include <InterViews/window.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <string.h>
#include "dsp_app.h"
#include "genmenu.h"
#include "cgidbg.h"
#include "mkstr.h"
#include "portable.h"
#include "xk_tab.h"
#include <InterViews/enter-scope.h>
#include <OS/enter-scope.h>
#include "file_view.h"

class WindowMenuText: public WindowMenu {
	void check_release();
	virtual Action * set_action(PullDownEntry * i) ;
	FileView & file_view ;
public:
	WindowMenuText(FileView& v):WindowMenu(),file_view(v) {}

	virtual void clear_selected() {}

	void text_help_file();
	void text_help_out();

	void page_down();
    void page_up();
    void end();
    void begin();
    void line_down();
    void line_up();
    void to_line();
    void ahead_lines();
    void save_file();
    void delete_window();

};


void WindowMenuText::check_release()
{
	file_view.menu_keyboard()->check_release();
}

typedef void (WindowMenuText::*ActionType)();
class ActionWindowMenuText: public RecAction {
	WindowMenuText * gr ;
	ActionType the_action ;
public:
	ActionWindowMenuText(MenuKeyboard * k, WindowMenuText * g,
		PullDownEntry & desc, ActionType a);
	ActionWindowMenuText(ActionType a):RecAction(0,0),the_action(a){}
	void force_execute() {record(); (gr->*the_action)();}
	void execute();
	ActionType action() {return the_action;}
};

ActionWindowMenuText::ActionWindowMenuText(MenuKeyboard * k,
	WindowMenuText * g, PullDownEntry & desc, ActionType a):
	RecAction(k,&desc),
	gr(g),
	the_action(a)
{
	Resource::ref(this);
}

void ActionWindowMenuText::execute()
{
    if (!DspApplication::user_input_allowed()) return ;
    record();
    (gr->*the_action)();
}




#define declare_WindowMenuText_member(name) \
static ActionWindowMenuText name (&(WindowMenuText::name)) ; \
void WindowMenuText::name()
	

declare_WindowMenuText_member(page_up)
{
	check_release();
	file_view.page_up();
}

declare_WindowMenuText_member(page_down)
{
	check_release();
	file_view.page_down();
}

declare_WindowMenuText_member(end)
{
	check_release();
	file_view.end();
}

declare_WindowMenuText_member(begin)
{
	check_release();
	file_view.begin();
}

declare_WindowMenuText_member(line_down)
{
	check_release();
	file_view.line_down();
}

declare_WindowMenuText_member(line_up)
{
	check_release();
	file_view.line_up();
}

declare_WindowMenuText_member(to_line)
{
	check_release();
	file_view.to_line();
}

declare_WindowMenuText_member(ahead_lines)
{
	check_release();
	file_view.ahead_lines();
}

declare_WindowMenuText_member(save_file)
{
	check_release();
	file_view.save_file();
}

declare_WindowMenuText_member(delete_window)
{
	check_release();
	file_view.delete_window();
}

declare_WindowMenuText_member(text_help_file)
{
	check_release();
	DspApplication::display_help_file("txt_file");
}

declare_WindowMenuText_member(text_help_out)
{
	check_release();
	DspApplication::display_help_file("txt_out");
}


static PullDownDescribe text_help_menu[] = {
	{ "listing output from a DSP process",XK_F1,&text_help_out},
	{ "moving though and saving file",XK_F1,&text_help_file},
	{ nil}
};

static PullDownDescribe move_menu[] = {
	{"ahead one page", XK_Next, &page_down},
	{"back one page", XK_Prior, &page_up},
	{"to last page", XK_End, &end},
	{"to first page", XK_Home, &begin},
	{"ahead one line", XK_Down, &line_down},
	{"back one line", XK_Up, &line_up},
	{"to line", XK_Tab, &to_line},
	{"ahead lines (- for back)", XK_s_ + XK_Tab, &ahead_lines},
	{ "save file", XK_c_ + XK_S,&save_file},
    { nil}
};


static PullDownDescribe text_main_menu[] = {
	{ "Help",XK_F1,nil,text_help_menu},
	{ "Move thorugh and save file",XK_F2,nil,move_menu},
	{ nil}
};

static PullDownDescribe text_menu_tree = {0,0,0,text_main_menu};

Action * WindowMenuText::set_action(PullDownEntry * i)
{
	ActionWindowMenuText * this_action = new ActionWindowMenuText(
		keyboard(),this,*i,
		((ActionWindowMenuText *) i->base_action())->action());
	i->action(this_action);
	return this_action ;
}

MenuKeyboard * FileView::build_menu(ivWidgetKit* kit, const ivLayoutKit& layout,
	ivStyle * style)
{
	WindowMenuText * menu_window = new WindowMenuText(*this) ;
	MenuKeyboard * ret = new MenuKeyboard(*kit, layout, style, menu_window,
		text_menu_tree);
	return ret ;
}



