/*

 Viewer       : C.
 Version      : 1.00.
 Date         : 26 September 1996.
 Distribution : freeware.
 Author(s)    : Willem Mestrom & Vincent Groenewold.

 Comment      : This is an example of a very simple viewer for AMIS. It
                shows C code in different colors to improve readability.

*/

#include <exec/types.h>
#include <clib/graphics_protos.h>
#include "viewer.h"

void __saveds __asm Display(register __a0 char *text,
										register __a1 char *buf,
										register __d0 long length,
										register __a5 struct EditWin *editwin);
void __saveds SwitchFunc(void);
void MyPrint(struct EditWin *editwin,char *text,long length);

struct GfxBase *GfxBase;
struct AMIS *AMIS;

struct Viewer C_Viewer={
	0,0,								/* must be zero */
	AMIS_0_97,						/* the version of AMIS which you need at least
											to use this viewer */
	0,									/* must be zero */
	"C-Source",						/* name of the viewer */
	0,									/* must be zero */
	"(#?.c|#?.h|#?.cpp|#?.cxx|#?.c++)",
										/* pattern of files to view with this viewer */
	0,									/* no special text at the start of a file */
	0,									/* no special text in file to recognize it */
	0,									/* no switch function */
	0,0,								/* flags */
	Display,							/* the display function */
	0,0,0,0,							/* standard control functions */
	1,0,0,-1,0,						/* normal lines */
	0,0,0,0,0,0,0,0,0,0,			/* standard control functions */
	"C-Source viewer v0.50||Written by Willem Mestrom & Vincent Groenewold."
};

long purple,purple2,leftoffset;

struct Viewer __saveds __asm *InitViewer(register __a0 struct AMIS *NewAMIS)
{
	AMIS=NewAMIS;
	C_Viewer.vw_font=AMIS->AMIS_Normal_Font;
	GfxBase=AMIS->AMIS_GfxBase;
	purple=-1;
	return(&C_Viewer);
}

/*		Example of using internal commands inside your own viewer
		To activate this function just add it to the C_Viewer structure.

void __saveds SwitchFunc()
{
	AMIS_InternalCommand("Request BODY=\"test\"");
}

*/

void __saveds __asm Display(register __a0 char *text,
										register __a1 char *buf,
										register __d0 long length,
										register __a5 struct EditWin *editwin)
{
	long	bufsign=0,charnum=0,tab,temp3,color;
	char	sign,cppcomment=0;

	leftoffset=-(editwin->ed_leftchar);

	if(purple==-1)
		purple=ObtainBestPen(AMIS->AMIS_ColorMap,0xaaaaaaaa,0x00000000,0xaaaaaaaa,0);

	purple2=ObtainBestPen(AMIS->AMIS_ColorMap,0xaaaaaaaa,0x00000000,0xaaaaaaaa,0);
	if(purple!=purple2)
	{
		ReleasePen(AMIS->AMIS_ColorMap,purple);
		purple=purple2;
	}
	else
	{
		ReleasePen(AMIS->AMIS_ColorMap,purple2);
	}

	color=editwin->ed_linesinfo[editwin->ed_line].li_viewerdata;
	if(color!=2)
	{
		if(text[0]=='#')
			color=purple;
		else
			color=1;
	}

	SetAPen(editwin->wn_rast,(color==0 ? 1 : color);
	SetBPen(editwin->wn_rast,0);
	tab=(long)editwin->ed_tabsize;
	if(tab==0) tab=8;
	while(charnum<length)
	{
		sign=text[charnum];
		if((sign=='/')&&(text[charnum+1]=='/')&&((color==1)||(color=purple)))
		{
			MyPrint(editwin,buf,bufsign);
			color=2; bufsign=0; cppcomment=1;
			SetAPen(editwin->wn_rast,color);
		}
		if((sign=='*')&&(text[charnum+1]=='/')&&(color==2))
		{
			buf[bufsign]='*'; bufsign++; buf[bufsign]='/'; bufsign++;
			MyPrint(editwin,buf,bufsign);
			color=1; bufsign=0; charnum+=2;
			SetAPen(editwin->wn_rast,color);
		}
		else
		{
			if(((sign=='{')||(sign=='}'))&&(color!=2))
			{
				MyPrint(editwin,buf,bufsign);
				color=3; bufsign=0;
				SetAPen(editwin->wn_rast,color);
				MyPrint(editwin,&sign,1);
				color=1; charnum++;
				SetAPen(editwin->wn_rast,color);
			}
		else
		{
				if((sign=='/')&&(text[charnum+1]=='*')&&(color!=2))
				{
					MyPrint(editwin,buf,bufsign);
					color=2; bufsign=0;
					SetAPen(editwin->wn_rast,color);
				}
			else
			{
				if((sign=='-')&&(text[charnum+1]=='>')&&(color!=2))
				{
					MyPrint(editwin,buf,bufsign); bufsign=0;
					buf[bufsign]='-'; bufsign++; buf[bufsign]='>'; bufsign++;
					color=7;
					SetAPen(editwin->wn_rast,color);
					MyPrint(editwin,buf,bufsign);
					bufsign=0; charnum+=2;
					color=1;
					SetAPen(editwin->wn_rast,color);
				}
			else
			{
				if(sign==9)
				{
					temp3=bufsign/tab;
					temp3++;
					temp3*=tab;
					temp3-=bufsign;
					while(temp3--)
					{
						buf[bufsign]=32;
						bufsign++;
					}
					charnum++;
				}
				else
				{
					buf[bufsign]=sign;
					bufsign++;
					charnum++;
						}
					}
				}
			}
		}
	}

	MyPrint(editwin,buf,bufsign);

	if(cppcomment)
		color=0;

	editwin->ed_linesinfo[editwin->ed_line+1].li_viewerdata=color;
}

void MyPrint(struct EditWin *editwin,char *text,long length)
{
	leftoffset+=length;
	if(leftoffset>0)
	{
		Text(editwin->wn_rast,text+length-leftoffset,leftoffset);
		leftoffset=0;
	}
}
