#include <stdio.h>
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>

#include "rn.h"
#include "rnlanguage.h"

/* this is used when we have either no prefs file at all */
void init_prefs(struct RnPrefs *prefs,char term)
{
	prefs->Bits=0;
	switch(term)
	{
	case VT100:
		strcpy(prefs->Normal,	"\033[m");
		strcpy(prefs->Header,	"\033[m");
		strcpy(prefs->From,		"\033[m");
		strcpy(prefs->Subject,	"\033[m");
		strcpy(prefs->Article,	"\033[m");
		strcpy(prefs->Include,	"\033[m");
		strcpy(prefs->Groupname,	"\033[1m");
		strcpy(prefs->More,		"\033[7m");
		strcpy(prefs->Ext2,		"\033[m");
		strcpy(prefs->Ext1,		"\033[m");
		break;
	case ANSI:
		strcpy(prefs->Normal,	"\033[m");
		strcpy(prefs->Header,	"\033[m");
		strcpy(prefs->From,		"\033[37m");
		strcpy(prefs->Subject,	"\033[36m");
		strcpy(prefs->Article,	"\033[m");
		strcpy(prefs->Include,	"\033[33m");
		strcpy(prefs->Groupname,	"\033[1m");
		strcpy(prefs->More,		"\033[7m");
		strcpy(prefs->Ext2,		"\033[m");
		strcpy(prefs->Ext1,		"\033[m");
		break;
	default:				/* plain ascii - no codes at all */
		prefs->Normal[0]=0;
		prefs->Header[0]=0;
		prefs->From[0]=0;
		prefs->Subject[0]=0;
		prefs->Article[0]=0;
		prefs->Include[0]=0;
		prefs->Groupname[0]=0;
		prefs->More[0]=0;
		prefs->Ext2[0]=0;
		prefs->Ext1[0]=0;
		break;
	}
}


void show_prefs(struct RnPrefs *prefs,int flag)
{	int i,j;

	if(flag==-1)	printf("\033[;H\033[2J\n");
	else			printf("\033[%d;H",flag+2);
	if(flag==0 || flag==-1)		printf("\t%sNormal\n",prefs->Normal);
	if(flag==1 || flag==-1)		printf("\t%sHeader%s\n",prefs->Header,prefs->Normal);
	if(flag==2 || flag==-1)		printf("\t%sFrom%s\n",prefs->From,prefs->Normal);
	if(flag==3 || flag==-1)		printf("\t%sSubject%s\n",prefs->Subject,prefs->Normal);
	if(flag==4 || flag==-1)		printf("\t%sArticle%s\n",prefs->Article,prefs->Normal);
	if(flag==5 || flag==-1)		printf("\t%sInclude%s\n",prefs->Include,prefs->Normal);
	if(flag==6 || flag==-1)		printf("\t%sGroupname%s\n",prefs->Groupname,prefs->Normal);
	if(flag==7 || flag==-1)		printf("\t%sMore%s\n",prefs->More,prefs->Normal);
	if(flag==8 || flag==-1)		printf("\t%sExtension2%s\n",prefs->Ext2,prefs->Normal);
	if(flag==9 || flag==-1)		printf("\t%sExtension1%s\n",prefs->Ext1,prefs->Normal);
	if(flag==10 || flag==-1)	printf("\t%s Headers \n",(prefs->Bits & RN_FULLHEADER) ? "Full" : "Short");
	if(flag==11 || flag==-1)	printf("\t%s\n",(prefs->Bits & RN_NOCLEAR) ? "No Screenclear" : "Screenclear   ");
	if(flag==12 || flag==-1)	printf("\t%s quotes\n",(prefs->Bits & RN_HIDEINCLUDE) ? "Hide" : "Show");
	if(flag==13 || flag==-1)	printf("\t%s date\n",(prefs->Bits & RN_SHOWDATE) ? "Show" : "Hide");
	if(flag==14 || flag==-1)	printf("\t%s organization\n",(prefs->Bits & RN_SHOWORG) ? "Show" : "Hide");
	if(flag==15 || flag==-1)	printf("\tGrab %s\n",(prefs->Bits & RN_GRABALL) ? "all groups" : "one group ");
	if(flag==16 || flag==-1)	printf("\tMore %s\n",(prefs->Bits & RN_NOMORE) ? "Off" : "On ");
	if(flag==17 || flag==-1)	printf("\tNew screen: %s\n",(prefs->Bits & RN_NOSCROLL) ? "Clear " : "Scroll");
	if(flag==18 || flag==-1)	printf("\tCursor: %s\n",(prefs->Bits & RN_NOCURSOR) ? "Hide  " : "Normal");

	if(flag==-1)
	{
		printf("\nCursor keys or ^N/^P to select        E,e,<CR> to edit        q to exit\n");
		for(i=0;i<8;i++)
		{
			printf("\033[%d;35H\033[%dm",2*i+2,30+i);
			for(j=0;j<8;j++)
				printf("\033[%dm[%c]\033[2C",40+j,48+i*8+j);
		}
		printf("\033[m\033[19;35H");
		for(j=0;j<8;j++)
			printf("\033[%dm[%c]\033[m  ",j,40+j);
	}
	fflush(stdout);
}

#define MODE_NORMAL 0
#define MODE_ESC	1
#define MODE_CSI	2
void edit_prefs(struct RnPrefs *prefs,int rows)
{	int line=1;
	unsigned char c,mode=MODE_NORMAL,done=0;

	show_prefs(prefs,-1);
	printf("\033[%d;0H*",line+2);
	while(!done)
	{
		if(WaitForChar(Input(),60000000))
		{
			Read(Input(),&c,1);
			switch(c)
			{
			case '\033':	/* ESC */
				mode=MODE_ESC;
				break;
			case 0x9b:		/* csi */
				mode=MODE_CSI;
				break;
			case '[':
				if(mode==MODE_ESC)
					mode=MODE_CSI;
				break;
			case 0x10:
				mode=MODE_CSI;	/* fall thru */
			case 'A':
				if(mode==MODE_CSI && line>1)
				{
					printf("\033[%d;0H \033[%d;0H*",line+2,line+1);
					line--;
					mode=MODE_NORMAL;
				}
				break;
			case 0x0e:
				mode=MODE_CSI;	/* fall thru */
			case 'B':
				if(mode==MODE_CSI && line<18)
				{
					printf("\033[%d;0H \033[%d;0H*",line+2,line+3);
					line++;
					mode=MODE_NORMAL;
				}
				break;
			case 0x0a:
			case 0x0d:
			case ' ':
			case 'e':
			case 'E':
				if(line<10)	/* if it is a color selection, prompt for a new code */
				{
					printf("\033[22;30HSelect a definition (code from the table) :");
					if(WaitForChar(Input(),60000000))
					{
						Read(Input(),&c,1);
						if(c>47 && c<112)
							sprintf((char *)prefs+10*line,"\033[%d;%dm",30+(c-48)/8,40+(c-48)%8);
						if(c>39 && c<48)
							sprintf((char *)prefs+10*line,"\033[%dm",c-40);
						show_prefs(prefs,line);
					}
					printf("\033[22;30H\033[K");
				}
				else	/* boolean values are just flipped and refreshed */
				{
					if(line>9 && line<19)
						prefs->Bits^= 1L<<(line-10);
					show_prefs(prefs,line);
				}
				printf("\033[%d;0H*",line+2);
				break;
			case 0x03:
			case 'q':
			case 'Q':
				if(mode==MODE_NORMAL)
					done=TRUE;
				else
					mode=MODE_NORMAL;
				break;
			default:
				mode=MODE_NORMAL;
				break;
			}
			fflush(stdout);
		}
		if(SetSignal(SIGBREAKF_CTRL_C,0) & SIGBREAKF_CTRL_C)
			done=TRUE;
	}
	printf("\033[%d;0H\n",rows);
	fflush(stdout);
}


void read_prefs(struct RnPrefs *prefs,char *name,char term)
{	long handle;
	int len;

	if(handle=Open(name,MODE_OLDFILE))	/* luetaan kotidirikasta .newsrc */
	{
		len=Read(handle,(char *)prefs,sizeof(struct RnPrefs));
		if(!len || len<0)	init_prefs(prefs,term);
		Close(handle);
	}
	else
	{
		printf(printout(MSG_CANT_OPEN),name);
		init_prefs(prefs,term);
	}
}

void write_prefs(struct RnPrefs *prefs,char *name)
{	long handle;

	if(handle=Open(name,MODE_NEWFILE)) 
	{
		Write(handle,(char *)prefs,sizeof(struct RnPrefs));
		Close(handle);
	}
	else
		printf(printout(MSG_NOT_WRITTEN),name);
}

