/****************************************************************
 ***                                                          ***
 ***     text.c                                               ***
 ***          simple EZ_Text widget demo                      ***
 ***                                                          ***
 ***************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include "EZ.h"

#define COMMENT_FONT  "-*-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*"
#define TYPE_FONT     "-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*"
#define CONTROL_FONT  "-Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-*"
#define CPP_FONT      "-Adobe-Times-Bold-I-Normal--*-120-*-*-*-*-*-*"

/***********************************************************************/
static void Load_CSRC_File( char *file);

EZ_Widget *fileSelector, *executor, *textW;
/***********************************************************************/
static void fileSelectorCallBack( EZ_Widget *widget, void *data)
{
  int length;
  char *fname = EZ_GetFileSelectorSelection(fileSelector);
  if( fname )
    {
      length = strlen(fname);
      if(length > 2 && fname[length-2] == '.' && fname[length-1] == 'c')
	{ 
	  /* a C src file */
	  EZ_FreezeWidget(textW);
	  Load_CSRC_File(fname);
	  EZ_TextBeginningOfBuffer(textW);
	  EZ_UnFreezeWidget(textW);
	  EZ_DisplayWidget(textW);
	}
      else 
	{
	  struct stat fstat;
	  if((stat(fname, &fstat) >= 0) && (fstat.st_mode & S_IFREG))
	    {
	      if(access(fname, X_OK) == 0)
		{
		  EZ_SetExecutorCommand(executor,fname, NULL);
		  EZ_DisplayWidget(executor);	      
		}
	      else
		{
		  EZ_TextLoadFile(textW,fname);
		  EZ_TextBeginningOfBuffer(textW);
		  EZ_DisplayWidget(textW);
		}
	    }
	}
    }
}
/**************************************************************************/

main(int ac, char **av)
{
  EZ_Widget *tmp;
  EZ_Initialize(ac,av,0);
  EZ_DisableSliderDepression();

  fileSelector = EZ_CreateFileSelector(NULL, NULL);
  EZ_SetWidgetCallBack(fileSelector, fileSelectorCallBack, NULL);
  executor = EZ_CreateExecutor(NULL);
  EZ_ConfigureWidget(executor,
		     EZ_WIDTH_HINT,200, EZ_HEIGHT_HINT, 200, 0);
  tmp = EZ_CreateFrame(NULL, NULL);
  EZ_ConfigureWidget(tmp, EZ_BORDER_TYPE, EZ_BORDER_UP, EZ_BORDER_WIDTH, 3, 
		     EZ_EMBEDER,1,
		     EZ_BACKGROUND, "#dfdfdf", 0);

  textW = EZ_CreateTextWidget(tmp, 0,1,1);  /* the text widget  */
  EZ_DisableImageDithering();
  EZ_ConfigureWidget(textW,
		     EZ_IMAGE_FILE, "brick1.gif",   /* bg tile  */
		     EZ_WIDTH,400, EZ_HEIGHT, 400,
		     0);

  EZ_DisplayWidget(fileSelector); 

  EZ_EventMainLoop();
}

/*********************************************************************************************/
#define IS_WHITE_SPACE(c)  (c == ' ' || c == '\t' || c == '\n')

static EZ_TextProperty *comment = NULL, *types = NULL;
static EZ_TextProperty *control = NULL, *cpp = NULL, *ez_func = NULL;

static void Load_CSRC_File( char *file)
{
  FILE *fp, *fopen();
  char str[1024], *tmp, *tmp1, c;
  int  in_comment = 0, i, count, length;

  EZ_TextClear(textW);
  fp = fopen(file, "r");
  if(fp == (FILE *)NULL)
    {
      sprintf(str, "Cannot Open %s",file);
      EZ_TextInsertString(textW, str);
      return;
    }

  comment = EZ_GetTextProperty(EZ_FONT_NAME, COMMENT_FONT,
			       EZ_FOREGROUND, "gray42", 0);
  types   = EZ_GetTextProperty(EZ_FONT_NAME, TYPE_FONT, 
			       EZ_FOREGROUND, "#ff0000", 0);
  control = EZ_GetTextProperty(EZ_FONT_NAME, CONTROL_FONT,
			       EZ_FOREGROUND, "#ffff00", 0);
  cpp     = EZ_GetTextProperty(EZ_FONT_NAME, CPP_FONT,
			       EZ_FOREGROUND, "#ff00ff", 0);
  ez_func = EZ_GetTextProperty(EZ_FONT_NAME, CPP_FONT,
			       EZ_FOREGROUND,"#0000ff",0);      

  while(fgets(str, 1023, fp))
    {
      tmp = str;
      length = strlen(str);
      i = 0;
      count = 0;
      while(count < length)
	{
	  if(in_comment)
	    {
	      while(tmp[i])
		{
		  if(tmp[i] == '*' && tmp[i+1] == '/')
		    {
		      c = tmp[i+2]; tmp[i+2] = 0;
		      EZ_TextInsertStringWithProperty(textW,tmp, comment);
		      in_comment = 0;
		      count += 2; 
		      tmp[i+2] = c;
		      tmp = tmp + i+2;
		      i = 0;
		      break;
		    }
		  i++;
		  count++;
		}
	      if(tmp[i] == 0)
		EZ_TextInsertStringWithProperty(textW,tmp, comment);
	      continue;
	    }

	  while(IS_WHITE_SPACE(tmp[i])) { count++; i++;}
	  if(i)
	    {
	      c = tmp[i]; tmp[i] = 0;
	      EZ_TextInsertStringWithProperty(textW,tmp, NULL);
	      tmp[i] = c;
	      tmp = tmp + i;
	      i = 0;
	    }
	  
	  if(!strncmp(tmp, "/*", 2))
	    {
	      in_comment = 1;
	      continue;
	      i = 0;
	    }
	  else if(tmp[0] == '#')
	    {
	      int iscpp = 0;
	      if(!strncmp(tmp, "#define", 7) ||
		 !strncmp(tmp, "#include", 8) ||
		 !strncmp(tmp, "#undef", 6) ||
		 !strncmp(tmp, "#ifdef", 6) ||
		 !strncmp(tmp, "#else", 5) ||
		 !strncmp(tmp, "#endif", 6) ||
		 !strncmp(tmp, "#if", 3))
		iscpp = 1;

	      i = 0;
	      while( !IS_WHITE_SPACE(tmp[i])) { i++, count++;}
	      c = tmp[i]; tmp[i] = 0;
	      EZ_TextInsertStringWithProperty(textW,tmp, iscpp == 0? NULL : cpp);
	      tmp[i] = c;
	      tmp = tmp + i;
	      i = 0;
	      continue;
	    }
	  else 
	    {
	      i = 0;
	      if(isalpha(tmp[i]))
		{
		  while(isalpha(tmp[i]) || tmp[i] == '_') { i++; count++;}
		  if(i)
		    {
		      c = tmp[i]; tmp[i] = 0;
		      if(!strncmp(tmp, "EZ_", 3))
			EZ_TextInsertStringWithProperty(textW,tmp, ez_func);	     
		      else if(!strncmp(tmp, "int", 3) ||
			      !strncmp(tmp, "float", 5) ||
			      !strncmp(tmp, "char", 4) ||
			      !strncmp(tmp, "unsigned", 8) ||
			      !strncmp(tmp, "long", 4) ||
			      !strncmp(tmp, "short", 5) ||
			      !strncmp(tmp, "typedef", 7) ||
			      !strncmp(tmp, "struct", 5) ||
			      !strncmp(tmp, "union", 5) ||
			      !strncmp(tmp, "double", 5) ||
			      !strncmp(tmp, "register", 8) ||
			      !strncmp(tmp, "enum", 4) ||
			      !strncmp(tmp, "extern", 6) ||
			      !strncmp(tmp, "static", 6) ||
			      !strncmp(tmp, "void", 4))
			EZ_TextInsertStringWithProperty(textW,tmp, types); 
		      else if(!strncmp(tmp, "if", 2) ||
			      !strncmp(tmp, "else", 4) ||
			      !strncmp(tmp, "do", 2) ||
			      !strncmp(tmp, "while", 5) ||
			      !strncmp(tmp, "for", 3) ||
			      !strncmp(tmp, "return", 6) ||
			      !strncmp(tmp, "case", 4) ||
			      !strncmp(tmp, "switch", 6) ||
			      !strncmp(tmp, "break", 5) ||
			      !strncmp(tmp, "continue", 8) ||
			      !strncmp(tmp, "exit", 4) ||
			      !strncmp(tmp, "default", 7) ||
			      !strncmp(tmp, "goto", 4))
			EZ_TextInsertStringWithProperty(textW,tmp, control); 
		      else
			EZ_TextInsertStringWithProperty(textW,tmp, NULL); 

		      tmp[i] = c;
		      tmp = tmp+i;
		      i = 0;
		      continue;
		    }
		  continue;
		}
	      else
		{
		  while(! IS_WHITE_SPACE(tmp[i])) { i++; count++;}
		  if(i)
		    {
		      c = tmp[i]; tmp[i] = 0;
		      EZ_TextInsertStringWithProperty(textW,tmp, NULL);
		      tmp[i] = c;
		      tmp = tmp + i;
		      i = 0;
		    }
		  continue;
		}
	    }
	}
    }
}
		    
		  

      
      
