/*
 *   Copyright 1992, 1993, 1994 John Melton (G0ORX/N6LYT)
 *              All Rights Reserved
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 1, or (at your option)
 *   any later version.
 *
 *   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 the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*
	viewtext.c

	Simple X-Windows program to view an ascii text message directly from
	a pacsat download file.

	John Melton
	G0ORX, N6LYT

	4 Charlwoods Close
	Copthorne
	West Sussex
	RH10 3QZ
	England

	INTERNET:	g0orx@amsat.org
			n6lyt@amsat.org
			john@images.demon.co.uk
			J.D.Melton@slh0613.icl.wins.co.uk

	History:

	0.1	Initial version.			G0ORX
	0.2	Converted to Xaw.			G4KLX
	0.3	Added display of ZIP and LHA files.	G4KLX
*/

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Text.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Viewport.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <dirent.h>
#include <signal.h>
#include <time.h>

#include "xawutils.h"
#include "header.h"
#include "ftl0.h"

Display *dpy;

XtAppContext app_context;

typedef struct
{
	XFontStruct *bold_font, *button_font, *text_font;
}
Resources;

Resources  resources;

Widget toplevel, compwindow, quitbutton, replybutton, datawindow;

static XtResource resource_list[] =
{
	{"boldFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
		XtOffsetOf(Resources, bold_font), XtRString, XtDefaultFont},
	{"buttonFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
		XtOffsetOf(Resources, button_font), XtRString, XtDefaultFont},
	{"textFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
		XtOffsetOf(Resources, text_font), XtRString, XtDefaultFont}
};

static Arg shell_args[] =
{
	{XtNtitle,		(XtArgVal)NULL}
};

static Arg form_args[] =
{
	{XtNdefaultDistance,	(XtArgVal)0}
};

static Arg button_args[] =
{
	{XtNcallback,		(XtArgVal)NULL},
	{XtNlabel,		(XtArgVal)NULL},
	{XtNfromHoriz,		(XtArgVal)NULL},
	{XtNfont,		(XtArgVal)NULL},
	{XtNresize,		(XtArgVal)False},
	{XtNvertDistance,	(XtArgVal)6},
	{XtNhorizDistance,	(XtArgVal)8},
	{XtNtop,		XtChainTop},
	{XtNbottom,		XtChainTop},
	{XtNleft,		XtChainLeft},
	{XtNright,		XtChainLeft}
};

static Arg window_args[] =
{
	{XtNfromVert,		(XtArgVal)NULL},
	{XtNbackground,		(XtArgVal)NULL},
	{XtNfont,		(XtArgVal)NULL},
	{XtNcursor,		(XtArgVal)NULL},
	{XtNwidth,		(XtArgVal)600},
	{XtNheight,		(XtArgVal)250},
	{XtNvertDistance,	(XtArgVal)6},
	{XtNscrollVertical,	XawtextScrollAlways},
	{XtNeditType,		XawtextEdit},
	{XtNtype,		XawAsciiString},
	{XtNdisplayNonprinting,	False},
	{XtNdisplayCaret,	False},
	{XtNwrap,		(XtArgVal)XawtextWrapLine},
	{XtNautoFill,		True}
};

char *fileName;

void QuitCb(Widget w, XtPointer client_data, XtPointer call_data)
{
	XtDestroyApplicationContext(app_context);

	exit(0);
}

void ViewText(void)
{
	char *pBuffer;
	FILE *hFile;
	FILE *hOut;
	int headerSize;
	HEADER *pHeader;
	int nBytes;
	int status;
	XawTextPosition pos = 0;
	XawTextBlock tt;
	char command[40], title[20];
	char compFile[20], viewFile[20];
	time_t t;
	
	/* open the file */
	if ((hFile = fopen(fileName, "r")) == NULL)
	{
		MessageBox("Cannot open input file");
		return;
	}

	pBuffer = XtMalloc(1024);

	/* read in the header */
	nBytes = fread(pBuffer, 1, 1024, hFile);

	/* extracting the header */
	if ((pHeader = ExtractHeader(pBuffer, nBytes, &headerSize)) == NULL)
	{
		MessageBox("Cannot extract PACSAT header");
		fclose(hFile);
		return;
	}

	strcpy(title, fileName);

	if (pHeader->compression != 0 && pHeader->compression != 255)
	{
		time(&t);
	
		sprintf(compFile, "%x.comp", (int)t);
		sprintf(viewFile, "%x.view", (int)t);
	
		fseek(hFile, pHeader->bodyOffset, SEEK_SET);

		if ((hOut = fopen(compFile, "w")) == NULL)
		{
			MessageBox("Cannot open output file");
			return;
		}

		while ((nBytes = fread(pBuffer, 1, 1024, hFile)) > 0)
			fwrite(pBuffer, 1, nBytes, hOut);

		fclose(hFile);
		fclose(hOut);
	
		switch (pHeader->compression)
		{
		case 2:
			sprintf(command, "unzip -p %s > %s", compFile, viewFile);
			strcat(title, " (pkzip)");
			break;
		case 3:
			sprintf(command, "lha -pq %s > %s", compFile, viewFile);
			strcat(title, " (lha)");
			break;
		default:
			break;
		}

		status = system(command);

		if (status == 127 || status < 0)
		{
			unlink(compFile);
			MessageBox("Cannot run unzip/lha");
			return;
		}

		if ((hFile = fopen(viewFile, "r")) == NULL)
		{
			unlink(compFile);
			MessageBox("Cannot open input file");
			return;
		}
	}
	
	XtVaSetValues(toplevel, XtNtitle, title, NULL);

	if (strlen(pHeader->title) == 0)
		nBytes = sprintf(pBuffer, "To: %s\nFrom: %s\nTitle: %s\n%s\n\n",
				pHeader->destination,
				pHeader->source,
				pHeader->fileName,
				"----------------------------------------");
	else
		nBytes = sprintf(pBuffer, "To: %s\nFrom: %s\nTitle: %s\n%s\n\n",
				pHeader->destination,
				pHeader->source,
				pHeader->title,
				"----------------------------------------");

	tt.firstPos = 0;
	tt.ptr      = pBuffer;
	tt.length   = nBytes;
	tt.format   = FMT8BIT;

	XawTextReplace(datawindow, pos, pos, &tt);

	pos += nBytes;

	/* now copy in the text */
	if (pHeader->compression == 0)
		fseek(hFile, pHeader->bodyOffset, SEEK_SET);

	while ((nBytes = fread(pBuffer, 1, 1024, hFile)) > 0)
	{
		tt.firstPos = 0;
		tt.ptr      = pBuffer;
		tt.length   = nBytes;
		tt.format   = FMT8BIT;

		XawTextReplace(datawindow, pos, pos, &tt);

		pos += nBytes;
	}

	fclose(hFile);

	if (pHeader->compression != 0)
	{
		unlink(compFile);
		unlink(viewFile);
	}

	XtFree((char *)pHeader);
	XtFree(pBuffer);
}

void signal_child(int s)
{
        int pid, pstatus;

	signal(SIGCHLD, signal_child);

        pid = wait(&pstatus);
}

void ReplyCb(Widget w, XtPointer client_data, XtPointer call_data)
{
        int pid;

        if ((pid = fork()) == 0)
        {
                /* the child process */
                execlp("message", "message", fileName, NULL);
        }
        else if (pid > 0)
        {
                /* success */
        }
        else
        {
		MessageBox("Cannot fork message");
        }
}

int main(int argc, char **argv)
{
	static XtCallbackRec callback[2];

	signal(SIGCHLD, signal_child);

	if (argc == 1)
	{
		fprintf(stderr, "usage: viewtext <file-name>\n");
		return(1);
	}

	toplevel = XtAppInitialize(&app_context, "Xpb", NULL, 0, &argc, argv,
				NULL, shell_args, XtNumber(shell_args));

	dpy  = XtDisplay(toplevel);

	XtGetApplicationResources(toplevel, &resources,
				resource_list, XtNumber(resource_list),
				NULL, ZERO);

	compwindow = XtCreateManagedWidget("appForm", formWidgetClass,
				toplevel, form_args, XtNumber(form_args));

	callback[0].callback = QuitCb;
	callback[0].closure  = toplevel;
	button_args[0].value = (XtArgVal)callback;
	button_args[1].value = (XtArgVal)"Quit";
	button_args[3].value = (XtArgVal)resources.button_font;
	quitbutton = XtCreateManagedWidget("quitButton", commandWidgetClass,
				compwindow, button_args, XtNumber(button_args));

	callback[0].callback = ReplyCb;
	callback[0].closure  = toplevel;
	button_args[0].value = (XtArgVal)callback;
	button_args[1].value = (XtArgVal)"Reply";
	button_args[2].value = (XtArgVal)quitbutton;
	replybutton = XtCreateManagedWidget("replyButton", commandWidgetClass,
				compwindow, button_args, XtNumber(button_args));

	window_args[0].value = (XtArgVal)quitbutton;
	window_args[1].value = (XtArgVal)WhitePixel(dpy, DefaultScreen(dpy));
	window_args[2].value = (XtArgVal)resources.text_font;
	datawindow = XtCreateManagedWidget("viewText", asciiTextWidgetClass,
				compwindow, window_args, XtNumber(window_args));

	createMessagePopup(resources.bold_font, resources.button_font);

	fileName = argv[1];
	ViewText();

	XtRealizeWidget(toplevel);
				
	XtAppMainLoop(app_context);
	
	return(0);
}

