//
// GWBookmarks.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 GWBookmarks class which
//   deal with the opening of windows.
//
#include "GWBookmarks.h"
#include "xvgopher.h"
#include "cursor.h"
#include "icons.h"
#include <fstream.h>
#include <string.h>
#include <xview/svrimage.h>
#include <xview/icon.h>
#include <xview/defaults.h>


#define	KEY_SAVE_BTN		30010
#define	KEY_SAVE_TXT		30011


GWBookmarks	*bookmarks;


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


//***************************************************************************
// GWBookmarks::~GWBookmarks()
//
GWBookmarks::~GWBookmarks()
{
	write_bookmarks();
}


//***************************************************************************
// int GWBookmarks::open(Response *resp)
// PURPOSE:
//   This  will  create a window in which the bookmarks directory will be
//   displayed.
//
int GWBookmarks::open(Response *resp)
{
	if (GWList::open(resp) != OK)
		return NOTOK;

	int	left = 8;		// Position of leftmost button in window
	
	//
	// 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);

	//
	//   Now  some  things  which  need  to  be  set for both FRAMEs and
	//   FRAME_CMDs
	//
	xv_set(frame,
		FRAME_SHOW_FOOTER,				TRUE,
		FRAME_RIGHT_FOOTER,				"Local bookmarks",
		FRAME_DONE_PROC,				(void (*)(Frame)) done_proc,
		XV_KEY_DATA,					KEY_GWINDOW,	this,
		XV_SHOW,						preferences.get_popup_bookmarks(),
		FRAME_LABEL,					"Xvgopher Bookmarks",
		NULL);

	modify_list_menu();

	read_bookmarks();

	return OK;
}


//***************************************************************************
// void GWBookmarks::read_bookmarks()
//
void GWBookmarks::read_bookmarks()
{
	char		*home = getenv("HOME");
	if (!home)
		home = ".";
	char		filename[100];
	sprintf(filename, "%s/.xvgopher-bm", home);
	ifstream	in(filename);
	if (in.fail())
		return;

	xv_set(dir_list,
		XV_SHOW,					FALSE,
		NULL);
	char	buffer[10000];
	int		i = 0;
	while (!in.eof())
	{
		in.getline(buffer, 10000);
		if (in.eof())
			break;
		if (i == 0)	// First line of the file
		{
			//
			// The first line of the file is supposed to contain the version number.
			// However, if the file does not contain one, we will just assume that
			// the file was created with version 1.0
			//
			if (strncmp(buffer, "XvGo", 4) == 0)
			{
				//
				// We got a version number!
				//
				continue;	// There is only one version, so what are we worrying about???
			}
		}
		Response	*r = new Response(buffer);
		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);
}


//***************************************************************************
// void GWBookmarks::write_bookmarks()
//
void GWBookmarks::write_bookmarks()
{
	char		*home = getenv("HOME");
	if (!home)
		home = ".";
	char		filename[100];
	sprintf(filename, "%s/.xvgopher-bm", home);
	ofstream	out(filename);
	if (out.fail())
		return;

	int		n = (int) xv_get(dir_list, PANEL_LIST_NROWS);

	//
	// First put the version number in the file so that we can determine later on
	// if the file needs conversion or not.
	//
	out << "XvGo " << VERSION << "\n";

	for (int i = 0; i < n; i++)
	{
		Response	*r = (Response *) xv_get(dir_list, PANEL_LIST_CLIENT_DATA, i);
		out << r->get_type() << r->get_title() << "\t" << r->get_command() << "\t" <<
				r->get_server() << "\t" << r->get_port() << "\n";
	}
	out.close();
}


//***************************************************************************
// void GWBookmarks::row_deselect(int row, Response *resp)
//
void GWBookmarks::row_deselect(int row, Response *resp)
{
	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);

	row = row;
	resp = resp;
	//
	// Hide the button and the text item
	//
	xv_set(save_btn,
		PANEL_INACTIVE,		TRUE,
		NULL);
	xv_set(save_txt,
		PANEL_INACTIVE,		TRUE,
		NULL);

	//
	// The menu of the dir_list has the remove item.  This needs to be made inactive.
	//
	xv_set(bookmark_mi,
		MENU_INACTIVE,					TRUE,
		NULL);
	xv_set(show_info_mi,
		MENU_INACTIVE,					TRUE,
		NULL);
}


//***************************************************************************
// void GWBookmarks::row_select(int row, Response *resp)
//
void GWBookmarks::row_select(int row, Response *resp)
{
	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);

	row = row;
	resp = resp;
	//
	// Show the button and the text item if the selected item is savable
	//
	if (strchr("09", resp->get_type()))
	{
		xv_set(save_btn,
			PANEL_INACTIVE,		FALSE,
			NULL);
		xv_set(save_txt,
			PANEL_INACTIVE,		FALSE,
			NULL);
	}

	//
	// The menu of the dir_list has the remove item.  This needs to be made active.
	//
	xv_set(bookmark_mi,
		MENU_INACTIVE,					FALSE,
		NULL);
	xv_set(show_info_mi,
		MENU_INACTIVE,					FALSE,
		NULL);
}


//***************************************************************************
// void GWBookmarks::show()
//
void GWBookmarks::show()
{
	xv_set(frame,
		XV_SHOW,				TRUE,
		NULL);
}


//***************************************************************************
// void GWBookmarks::add(Response *resp)
// PURPOSE:
//   Add a line to the list of bookmarks.
//
void GWBookmarks::add(Response *resp)
{
	xv_set(dir_list,
		XV_SHOW,					FALSE,
		NULL);

	int	n = (int) xv_get(dir_list, PANEL_LIST_NROWS);
	xv_set(dir_list,
		PANEL_LIST_INSERT,			n,
		PANEL_LIST_STRING,			n, resp->get_title(),
		PANEL_LIST_GLYPH,			n, get_image(resp->get_type()),
		PANEL_LIST_CLIENT_DATA,		n, resp,
		NULL);

	xv_set(dir_list,
		XV_SHOW,					TRUE,
		NULL);
}


//***************************************************************************
// void GWBookmarks::modify_list_menu()
//   Modify the Bookmarks List menu so that if contains the following items:
//		Remove bookmark
//		Show item info
//
void GWBookmarks::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,					"Remove bookmark",
		MENU_NOTIFY_PROC,				remove_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,					FALSE,
		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 GWBookmarks::remove_bookmark_proc(Menu menu, Menu_item mi)
//
void GWBookmarks::remove_bookmark_proc(Menu menu, Menu_item mi)
{
	GWBookmarks		*gwindow = (GWBookmarks *) xv_get(mi, XV_KEY_DATA, KEY_GWINDOW);

	//
	// First make sure that there really is a row selected...
	//
	if (!xv_get(gwindow->dir_list, PANEL_LIST_SELECTED, gwindow->current_selected))
		return;

	menu = menu;
	//
	// Some row was selected and we need to remove the row from the list.
	//
	Response *r = (Response *) xv_get(gwindow->dir_list, PANEL_LIST_CLIENT_DATA, gwindow->current_selected);
	delete r;
	xv_set(gwindow->dir_list,
		PANEL_LIST_DELETE,			gwindow->current_selected,
		NULL);
	xv_set(gwindow->bookmark_mi,
		MENU_INACTIVE,					TRUE,
		NULL);
}


//***************************************************************************
// void GWBookmarks::done_proc(Frame frame)
//   This gets called whenever a command frame is destroyed.  In the case
//   of the book marks window, we only need to hide the window.
//
void GWBookmarks::done_proc(Frame frame)
{
	xv_set(frame,
		XV_SHOW,				FALSE,
		NULL);
}


//***************************************************************************
