/*
**   YAM2NN - Usenet access for YAM p7 and newer
**   Copyright (C) 1999 Karol Bryd <kbryd@femina.com.pl>
**
**   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 2
**   of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

/*
** $Log$
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <proto/rexxsyslib.h>

#include <rexx/rxslib.h>
#include <rexx/rexxio.h>
#include <rexx/errors.h>

#include <dos/dos.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <utility/tagitem.h>

#include "get_folder_path.h"

extern char *Stptok(const char *s, char *tok, int toklen, const char *brk);
extern char *Stpblk(const char *str);
extern int Astcsma(char *s, char *p);

#define stpblk Stpblk
#define stptok Stptok
#define astcsma Astcsma

__stkargs void NewList(struct List * list);

#ifndef YOH
extern char * stristr(char * buf, char * str);
#endif
char current_user_path[108];
char tmp[1024];

struct NewsNode {
	struct NewsNode * next;
	struct NewsNode * prev;
	char * ngname;
	char * path;
	char folder[40];
};

// gets path for current user's directory

// this needs to be rewritten
int query_for_user(void)
{
	BPTR fh;
	char * ln;

	SPrintf(tmp, "/* */;OPTIONS RESULTS;ADDRESS YAM;USERINFO STEM u.;call open(f,'T:uitmp','w');call writeln(f,u.maildir);call close(f)");
	if(!(fh = Open("T:qfu.rexx", MODE_NEWFILE)))
		return(-1);
	Write(fh, tmp, strlen(tmp));
	Close(fh);
	Execute("rx T:qfu.rexx", NULL, NULL);
	if(!(fh = Open("T:uitmp", MODE_OLDFILE)))
		return(-1);
	Read(fh, current_user_path, sizeof(current_user_path));
	Close(fh);
	DeleteFile("T:qfu.rexx");
	DeleteFile("T:uitmp");
	if(ln = strchr(current_user_path, 10))
		*ln = 0;
	return(0);
}

#ifdef YOH

char * stristr(char * buf, char * str)
{
	register int len = strlen(buf);
	register int len2 = strlen(str);
	register int a;

	for(a = 0; a <= len - len2; a++)
		if(Strnicmp(&buf[a], str, len2) == 0)
			return(&buf[a]);
	return(0);
}

#endif

// scans YAM's folders and gets type of folder from .fconfig files

void scan_folders(struct List * folders)
{
	struct Folder * folder;
	BPTR fh;

	folder = (struct Folder *)folders->lh_Head;
	while(folder->f_next)
	{
		strcpy(tmp, current_user_path);
		AddPart(tmp, folder->f_path, sizeof(tmp));
		AddPart(tmp, ".fconfig", sizeof(tmp));
		if(fh = Open(tmp, MODE_OLDFILE))
		{
			char * fconfig, * equal;

			if(fconfig = AllocVec(1000, MEMF_ANY))
			{
				Read(fh, fconfig, 1000);
				equal = (char *)stristr(fconfig, "Type");
				if(equal = strchr(equal, '='))
				{
					equal++;
					equal = stpblk(equal);
					folder->f_type = atol(equal);
				}
				FreeVec(fconfig);
			}
			Close(fh);
		}
		folder = folder->f_next;
	}
}

// creates list of folders - only in YAM p7+

int build_folders_list(struct List * folders)
{
	BPTR folders_fh;
	int num = 0;

	strcpy(tmp, current_user_path);
	AddPart(tmp, ".folders", sizeof(tmp));
	if(!(folders_fh = Open(tmp, MODE_OLDFILE)))
		return(-2);  // perhaps no YAM P7
	FGets(folders_fh, tmp, sizeof(tmp));
	while(FGets(folders_fh, tmp, sizeof(tmp)))
	{
		if(Strnicmp(tmp, "@FOLDER", 7) == 0)
		{
			struct Folder * folder;
			char tmpbuf[256];

			FGets(folders_fh, tmp, sizeof(tmp));
			if(folder = AllocVec(sizeof(struct Folder), MEMF_ANY | MEMF_CLEAR))
			{
				folder->f_num = num++;
				if(!(stristr(tmp, ":")))
				{
					strcpy(tmpbuf, current_user_path);
					AddPart(tmpbuf, tmp, sizeof(tmpbuf));
				}
				else
					strcpy(tmpbuf, tmp);
				if(folder->f_path = AllocVec(strlen(tmpbuf) + 1, MEMF_ANY | MEMF_CLEAR))
					strcpy(folder->f_path, strtok(tmpbuf, "\n"));
				else
					return(-2);
				AddTail(folders, (struct Node *)folder);
			}
			else
				return(-2);
		}
		if(Strnicmp(tmp, "@SEPARATOR", 10) == 0)
			num++;
	}
	scan_folders(folders);
	Close(folders_fh);
	return(0);
}

void free_folders_list(struct List * folders)
{
	struct Folder * folder = (struct Folder *)folders->lh_Head;
	struct Folder * next;

	while(folder->f_next)
	{
		next = folder->f_next;
		FreeVec(folder->f_path);
		FreeVec(folder);
		folder = next;
	}
	FreeVec(folders);
}

// gets folder path

char * get_folder_path(struct List * folders, int type)
{
	struct Folder * folder = (struct Folder *)folders->lh_Head;

	while(folder->f_next)
	{
		if(folder->f_type == type)
			return(folder->f_path);
		folder = folder->f_next;
	}
	return(NULL);
}

// gets folder number

int get_folder_pos(struct List * folders, int type)
{
	struct Folder * folder = (struct Folder *)folders->lh_Head;

	while(folder->f_next)
	{
		if(folder->f_type == type)
			return(folder->f_num);
		folder = folder->f_next;
	}
	return(-1);
}

struct List * init_folder_list(void)
{
	static struct List * folders;

	if(!(folders = AllocVec(sizeof(struct List), MEMF_ANY | MEMF_CLEAR)))
		return(NULL);
	NewList(folders);
//	folders->lh_Head = (struct Node *)&folders->lh_Tail;
//	folders->lh_Tail = 0L;
//	folders->lh_TailPred = (struct Node *)&folders->lh_Head;
//	folders->lh_Type = 0;
	return(folders);
}

void save_folder_list(struct List * folders, struct List * newsgroups)
{
	struct Folder * folder;
	struct NewsNode * nc;
	BPTR fh;

	if(!folders)
		return;
	if(!(fh = Open("YAM:YAM2NN.folders", MODE_NEWFILE)))
		return;
	Write(fh, "Folderfiledate: -1\n", 19);
	folder = (struct Folder *)folders->lh_Head;
	while(folder->f_next)
	{
		if(newsgroups)
		{
			if((folder->f_type == INCOMING) || (folder->f_type == OUTGOING) || (folder->f_type == SENT) || (folder->f_type == DELETED))
			{
				SPrintf(tmp, "!%s!%ld!%ld!\n", folder->f_path, folder->f_num, folder->f_type);
				Write(fh, tmp, strlen(tmp));
			}
			else
			{
				for(nc = (struct NewsNode *)newsgroups->lh_Head; nc->next; nc = (struct NewsNode *)nc->next)
				{
					if(stristr(nc->path, FilePart(folder->f_path)))
					{
						SPrintf(tmp, "!%s!%ld!%ld!\n", folder->f_path, folder->f_num, folder->f_type);
						Write(fh, tmp, strlen(tmp));
						break;
					}
				}
			}
		}
		else
		{
			SPrintf(tmp, "!%s!%ld!%ld!\n", folder->f_path, folder->f_num, folder->f_type);
			Write(fh, tmp, strlen(tmp));
		}
		folder = folder->f_next;
	}
	Close(fh);
}

struct List * open_folder_list(void)
{
	struct Folder * folder;
	struct List * list;
	char name[108];
	BPTR fh;

	if(!(list = AllocVec(sizeof(struct List), MEMF_ANY | MEMF_CLEAR)))
		return(NULL);
	NewList(list);
//	list->lh_Head = (struct Node *)&list->lh_Tail;
//	list->lh_Tail = 0L;
//	list->lh_TailPred = (struct Node *)&list->lh_Head;
//	list->lh_Type = 0;
	if(!(fh = Open("YAM:YAM2NN.folders", MODE_OLDFILE)))
	{
		FreeVec(list);
		return(NULL);
	}
	while(FGets(fh, tmp, sizeof(tmp)))
	{
		char * start, * end;

		if(!(folder = AllocVec(sizeof(struct Folder), MEMF_ANY | MEMF_CLEAR)))
			break;
		if(end = strrchr(tmp, '!'))
			*end = 0;
		start = strrchr(tmp, '!');
		folder->f_type = atol(++start);
		*start = 0;
		if(end = strrchr(tmp, '!'))
			*end = 0;
		start = strrchr(tmp, '!');
		folder->f_num = atol(++start);
		*start = 0;
		if(end = strrchr(tmp, '!'))
			*end = 0;
		start = strrchr(tmp, '!');
		strcpy(name, ++start);
		if(folder->f_path = AllocVec(strlen(name) + 1, MEMF_ANY | MEMF_CLEAR))
			strcpy(folder->f_path, name);
		else
			return(NULL);
		AddTail(list, (struct Node *)folder);
	}
	Close(fh);
	return(list);
}

#ifdef YOH

void _main(void)
{
	struct List * folders;
	struct Folder * folder;

	if(SysBase->LibNode.lib_Version < 39)
		_exit(20);
	query_for_user();
	Printf("current user path: \'%s\'\n", current_user_path);
	if(!(folders = open_folder_list()))
	{
		folders = init_folder_list();
		if(build_folders_list(folders) != -2)
		{
			save_folder_list(folders, NULL);
			free_folders_list(folders);
			folders = open_folder_list();
			Printf("INCOMING: \'%s\'\n", get_folder_path(folders, INCOMING));
			Printf("DELETED at %ld position\n", get_folder_pos(folders, DELETED));
		}
		else
			_exit(-2);
	}
	folder = (struct Folder *)folders->lh_Head;
	folder = folder->f_next;
	Printf("Folderpath, foldernumber and foldertype ...\n");
	while(folder->f_next)
	{
		Printf("\'%s\' %ld %ld\n", folder->f_path, folder->f_num, folder->f_type);
		folder = folder->f_next;
	}
	free_folders_list(folders);
}

#endif
