//
// GWDirectory.cc
//
// (c) Copyright 1993, San Diego State University -- College of Sciences
//       (See the COPYRIGHT file for more Copyright information)
//
//   This  file  contains  the  routines  of the GWDirectory class which
//   deal with the opening of windows.
//
#include "GWDirectory.h"
#include "xvgopher.h"
#include "GWBookmarks.h"
#include "GWPref.h"
#include "GWAbout.h"
#include "GWGopher.h"
#include <xview/notice.h>
#include <stream.h>
#include <string.h>


#define	KEY_SAVE_BTN		30010
#define	KEY_SAVE_TXT		30011


//***************************************************************************
// GWDirectory::GWDirectory(Frame par)
//
GWDirectory::GWDirectory(Frame par)
{
	parent = par;
}


//***************************************************************************
// int GWDirectory::open(Response *resp)
// PURPOSE:
//   This  will  create a window in which a gopher directory will be
//   displayed.  There  is a special case for this window: it can be
//   the  first  window  created  for  this  program.  Hence, if the
//   parent  is  NULL, the window will NOT be a command window but a
//   regular window.
//
int GWDirectory::open(Response *resp)
{
	//
	// Let the base class create the window.  We will only add the buttons
	//
	if (GWList::open(resp) != OK)
		return NOTOK;

	int	left = 8;		// Position of leftmost button in window
	if (!parent)
	{
		//
		//   The main frame gets the Gopher menu button and the Quit
		//   button
		//
		Menu menu = (Menu) xv_create(NULL, MENU,
			MENU_NOTIFY_PROC,				menu_proc,
			MENU_ITEM,
				MENU_STRING,				"Bookmarks...",
				NULL,
			MENU_ITEM,
				MENU_STRING,				"Another Gopher...",
				NULL,
			MENU_ITEM,
				MENU_STRING,				"",
				MENU_FEEDBACK,				FALSE,
				NULL,
			MENU_ITEM,
				MENU_STRING,				"Preferences...",
				NULL,
			MENU_ITEM,
				MENU_STRING,				"",
				MENU_FEEDBACK,				FALSE,
				NULL,
			MENU_ITEM,
				MENU_STRING,				"About...",
				NULL,
			XV_KEY_DATA,					KEY_GWINDOW,	this,
			NULL);
		xv_create(panel, PANEL_BUTTON,
			XV_X,							8,
			XV_Y,							8,
			PANEL_LABEL_STRING,				"Gopher",
			PANEL_ITEM_MENU,				menu,
			NULL);

		//
		//   Since  we  still  want  to put the other buttons in this panel,
		//   we  need  to  make  sure  they  do  not overlap. That's why the
		//   variable 'left' has the pixel location of the next button.
		//
		left = 92;

		//
		// Since we are the parent of all windows, there is only one of us.  Therefore,
		// this is a good place to create the book marks window.
		// The Response parameter to the open member is really a dummy.
		//
		bookmarks = new GWBookmarks(frame);
		bookmarks->open(resp);

		//
		// The same holds true for the preferences window...
		//
		gwpref = new GWPref(frame);
		gwpref->open(resp);
	}

#if		USE_SAVE
	//
	// Create the save button and save text field.
	//
	Panel_item save_btn = (Panel_item) xv_create(panel, PANEL_BUTTON,
		XV_X,							left,
		XV_Y,							8,
		PANEL_LABEL_STRING,				"Save",
		PANEL_INACTIVE,					TRUE,
		NULL);
	Panel_item save_txt = (Panel_item) xv_create(panel, PANEL_TEXT,
		XV_X,							left + 56,
		XV_Y,							8,
		PANEL_LABEL_STRING,				"Save in:",
		PANEL_VALUE_DISPLAY_WIDTH,		260,
		PANEL_INACTIVE,					TRUE,
		NULL);

	xv_set(dir_list,
		XV_KEY_DATA,					KEY_SAVE_BTN,	save_btn,
		XV_KEY_DATA,					KEY_SAVE_TXT,	save_txt,
		NULL);
#endif	USE_SAVE

	//
	//   Now  some  things  which  need  to  be  set for both FRAMEs and
	//   FRAME_CMDs
	//
	xv_set(frame,
		XV_SHOW,						TRUE,
		FRAME_RIGHT_FOOTER,				info->get_server(),
		FRAME_DONE_PROC,				done_proc,
		NULL);

	//
	// Modify the list menu
	//
	modify_list_menu();

	//
	//   Let the user know that we are working on something...
	//
	frame_busy(frame);

	//
	//   Now we need to build the connection and get information from it
	//
	gopher = new Gopher(this);
	if (gopher->open(info->get_server(), info->get_port()) == NOTOK)		// Connection
	{
		xv_create(frame, NOTICE,
			NOTICE_MESSAGE_STRINGS,		"Unable to connect to remote gopher",
										info->get_server(),
										NULL,
			NOTICE_BUTTON_YES,			"Bummer",
			NOTICE_BLOCK_THREAD,		TRUE,
			NOTICE_LOCK_SCREEN,			TRUE,
			XV_SHOW,					TRUE,
			NULL);
		return NOTOK;
	}
	gopher->read(info->get_type(), info->get_command());					// Get info

	return OK;
}


//***************************************************************************
// void GWDirectory::modify_list_menu()
//   Modify the Directory List menu so that if contains the following items:
//		Set bookmark
//		Show item info
//
void GWDirectory::modify_list_menu()
{
	//
	// We want to modify the scrolling list's menu, so we need to get it,
	// add the items and then put it back.
	//
	Menu	m = (Menu) xv_get(dir_list, PANEL_ITEM_MENU);
	bookmark_mi = (Menu_item) xv_create(NULL, MENUITEM,
		MENU_STRING,					"Set bookmark",
		MENU_NOTIFY_PROC,				set_bookmark_proc,
		MENU_INACTIVE,					TRUE,
		XV_KEY_DATA,					KEY_GWINDOW, this,
		NULL);
	xv_set(m,
		MENU_APPEND_ITEM,				bookmark_mi,
		NULL);
	show_info_mi = (Menu_item) xv_create(NULL, MENUITEM,
		MENU_STRING,					"Show item info",
		MENU_NOTIFY_PROC,				show_item_info_proc,
		MENU_INACTIVE,					TRUE,
		XV_KEY_DATA,					KEY_GWINDOW, this,
		NULL);
	xv_set(m,
		MENU_APPEND_ITEM,				show_info_mi,
		NULL);
	xv_set(dir_list,
		PANEL_ITEM_MENU,				m,
		NULL);
}


//***************************************************************************
// void GWDirectory::row_deselect(int, Response *)
//
void GWDirectory::row_deselect(int, Response *)
{
#if		USE_SAVE
	//
	// Hide the button and the text item
	//
	Panel_item		save_btn = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_BTN);
	Panel_item		save_txt = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_TXT);

	xv_set(save_btn,
		PANEL_INACTIVE,		TRUE,
		NULL);
	xv_set(save_txt,
		PANEL_INACTIVE,		TRUE,
		NULL);
#endif	USE_SAVE
	if (!parent)
	{
		xv_set(bookmark_mi,
			MENU_INACTIVE,					TRUE,
			NULL);
		xv_set(show_info_mi,
			MENU_INACTIVE,					TRUE,
			NULL);
	}
}


//***************************************************************************
// void GWDirectory::row_select(int, Response *)
//
void GWDirectory::row_select(int, Response *)
{
#if		USE_SAVE
	//
	// Show the button and the text item if the selected item is savable
	//
	if (strchr("09", resp->get_type()))
	{
		Panel_item		save_btn = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_BTN);
		Panel_item		save_txt = (Panel_item) xv_get(dir_list, XV_KEY_DATA, KEY_SAVE_TXT);

		xv_set(save_btn,
			PANEL_INACTIVE,		FALSE,
			NULL);
		xv_set(save_txt,
			PANEL_INACTIVE,		FALSE,
			NULL);
	}
#endif	USE_SAVE
	xv_set(show_info_mi,
		MENU_INACTIVE,					FALSE,
		NULL);
	xv_set(bookmark_mi,
		MENU_INACTIVE,					FALSE,
		NULL);
}


//***************************************************************************
// void GWDirectory::display()
//
void GWDirectory::display()
{
	gopher->start_get();
	int		i = 0;
	char	*str;

	frame_unbusy(frame);
	xv_set(dir_list,
		XV_SHOW,					FALSE,
		NULL);
	while (str = gopher->get_next())
	{
		Response	*r = new Response(str);
		xv_set(dir_list,
			PANEL_LIST_INSERT,			i,
			PANEL_LIST_STRING,			i, r->get_title(),
			PANEL_LIST_GLYPH,			i, get_image(r->get_type()),
			PANEL_LIST_CLIENT_DATA,		i, r,
			NULL);
		i++;
	}
	xv_set(dir_list,
		XV_SHOW,					TRUE,
		NULL);
}


#if		USE_SAVE
//***************************************************************************
// void GWDirectory::save_notify(Panel_item item, Event *event)
//
void GWDirectory::save_notify(Panel_item item, Event *event)
{
	event = event;
	GWDirectory		*gwindow = (GWDirectory *) xv_get(item, XV_KEY_DATA, KEY_GWINDOW);
	Panel_item		save_txt = (Panel_item) xv_get(item, XV_KEY_DATA, KEY_SAVE_TXT);

	char	*filename = (char *) xv_get(save_txt, PANEL_VALUE);
}
#endif	USE_SAVE


//***************************************************************************
// void GWDirectory::menu_proc(Menu menu, Menu_item mi)
//
void GWDirectory::menu_proc(Menu menu, Menu_item mi)
{
	GWDirectory		*gwindow = (GWDirectory *) xv_get(menu, XV_KEY_DATA, KEY_GWINDOW);
	char			*item = (char *) xv_get(mi, MENU_STRING);

	if (strcmp(item, "Bookmarks...") == 0)
	{
		bookmarks->show();
	}
	else if (strcmp(item, "Preferences...") == 0)
	{
		//
		// Build a preferences window
		//
		gwpref->show();
	}
	else if (strcmp(item, "About...") == 0)
	{
		//
		// Build an About window
		//
		GWAbout	*about = new GWAbout(gwindow->frame);
		about->open(NULL);
	}
	else if (strcmp(item, "Another Gopher...") == 0)
	{
		//
		// Get information from the user about where to contact
		// a new gopher server.
		//
		GWGopher	*newgopher = new GWGopher(gwindow->frame);
		newgopher->open(gwindow->info);
	}
}


//***************************************************************************
// void GWDirectory::set_bookmark_proc(Menu menu, Menu_item mi)
//
void GWDirectory::set_bookmark_proc(Menu menu, Menu_item mi)
{
	GWDirectory		*gwindow = (GWDirectory *) xv_get(mi, XV_KEY_DATA, KEY_GWINDOW);

	menu = menu;
	if (gwindow->current_selected == -1)
	{
		//
		// No row is selected.  We will assume we want to add a bookmark pointing to the
		// current directory.  This is simple since we already have a Response object
		// for ourselves.
		//
		bookmarks->add(new Response(gwindow->info));
	}
	else
	{
		//
		// Some row was selected.  This is cool.  All we need to do now is retrieve the
		// data associated with that row and add it to the bookmark list.
		//
		Response		*r;
		r = (Response *) xv_get(gwindow->dir_list, PANEL_LIST_CLIENT_DATA, gwindow->current_selected);
		bookmarks->add(new Response(r));
	}
}



