/****************************************************************
 ***                                                          ***
 ***     text.c                                               ***
 ***          simple EZ_Text widget demo                      ***
 ***                                                          ***
 ***************************************************************/
#include <stdio.h>
#include <ctype.h>

#include "EZ.h"

static EZ_Widget *badc;         /* the master frame */

static EZ_Widget *tp_frame;         /* the master frame */
static EZ_Widget *textW;            /* the text widget  */
int cont = 1;
static void clean_exit(){ cont = 0;};
static void Load_CSRC_File();

/*************************************************************************/
static char *colors[] = {
  "red",
  "green",
  "blue",
  "yellow",
  "cyan",
  "magenta",
  "white",
  "gray",
  "black",
};
#define NCOLORS 9
/*************************************************************************/

static char *fonts[] = {
  "-*-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*",
  "-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*",
  "-Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-*",
  "-Adobe-Times-Bold-I-Normal--*-120-*-*-*-*-*-*",
  "-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*",
  "-*-Courier-Medium-R-Normal--*-180-*-*-*-*-*-*",
  "-Adobe-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-*",
  "-Adobe-Times-Bold-I-Normal--*-180-*-*-*-*-*-*",
  "-Adobe-Helvetica-Medium-R-Normal--*-240-*-*-*-*-*-*",
  "-*-Courier-Medium-R-Normal--*-240-*-*-*-*-*-*",
  "-Adobe-Helvetica-Bold-R-Normal--*-240-*-*-*-*-*-*",
  "-Adobe-Times-Bold-I-Normal--*-240-*-*-*-*-*-*",
};
#define NFONTS 12
#define COMMENT_FONT  fonts[0]
#define TYPE_FONT     fonts[1]
#define CONTROL_FONT  fonts[2]
#define CPP_FONT      fonts[3]

/**************************************************************************/
static void fcolorMCallback(menu)
     EZ_Widget *menu;
{
  int i = EZ_GetWidgetReturnedData(menu);
  if( i >= 0 && i < NCOLORS) 
    EZ_TextSetRegionForeground(textW, colors[i]);
}
/**************************************************************************/
static void bcolorMCallback(menu)
     EZ_Widget *menu;
{
  int i = EZ_GetWidgetReturnedData(menu);
  if( i >= 0 && i < NCOLORS) 
    EZ_TextSetRegionBackground(textW, colors[i]);
}
/**************************************************************************/
static void fontMCallback(menu) 
     EZ_Widget *menu;
{
  int i = EZ_GetWidgetReturnedData(menu);
  if( i >= 0 && i < NFONTS) 
    EZ_TextSetRegionFont(textW, fonts[i]);
}
static void underline_region(widget)
     EZ_Widget *widget;
{
  EZ_TextSetRegionUnderline(textW,1);
}
/**************************************************************************/
#define OPEN   101
#define OPENA  102
#define NEWF   103
#define SAVE   104
#define SAVEA  105
#define EXIT   106

static EZ_Widget *file_entry, *dialogue = NULL;

static void display_dialogue()
{
  if(dialogue == NULL)
    {
      dialogue = EZ_CreateFrame(NULL, "Please Enter a File Name");
      EZ_ConfigureWidget(dialogue, EZ_TRANSIENT, True, 0);
      file_entry = EZ_CreateEntry(dialogue, NULL);
    }
  EZ_SetGrab(dialogue);
  EZ_DisplayWidget(dialogue);
  EZ_SetFocusTo(file_entry);
}
/***********************************************************************/
static void replace_region_by_bitmap(menu, d)
     EZ_Widget *menu, *d;
{
  char *fname = EZ_GetEntryString(file_entry);
  EZ_TextReplaceRegionWithPixmap(textW, fname);
  EZ_HideWidget(dialogue);
  EZ_ReleaseGrab();
}
static void replace_callback(menu, d)
     EZ_Widget *menu; void *d;
{
  display_dialogue();
  EZ_SetWidgetCallBack(file_entry, replace_region_by_bitmap, NULL);
}
static void clear_region_tprop()
{
  EZ_TextSetRegionProperty(textW, NULL);
}
/***********************************************************************/

static void Load_Regular_File()
{
  int length;
  char *fname = EZ_GetEntryString(file_entry);
  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);
    }
  else  EZ_TextLoadFile(textW,fname);
  EZ_HideWidget(dialogue);
  EZ_ReleaseGrab();
}

static void Save_Regular_File()
{
  int length;
  char *fname = EZ_GetEntryString(file_entry);
  EZ_TextSaveText(textW, fname);
  EZ_HideWidget(dialogue);
  EZ_ReleaseGrab();
}
static void open_regular_file()
{
  display_dialogue();
  EZ_SetWidgetCallBack(file_entry,Load_Regular_File, NULL);
}
static void save_regular_file()
{
  display_dialogue();
  EZ_SetWidgetCallBack(file_entry,Save_Regular_File, NULL);
}
/***********************************************************************/
static void Load_Annotated_File()
{
  char *fname = EZ_GetEntryString(file_entry);  
  EZ_TextLoadAnnotatedFile(textW, fname);
  EZ_HideWidget(dialogue);
}

static void Save_Annotated_File()
{
  char *fname = EZ_GetEntryString(file_entry);  
  EZ_TextSaveAnnotatedText(textW, fname);
  EZ_HideWidget(dialogue);
}
/***********************************************************************/
static void fileMCallback(menu) 
     EZ_Widget *menu;
{
  char *fname;
  int i = EZ_GetWidgetReturnedData(menu);
  switch(i)
    {
    case OPEN:
      open_regular_file();
      break;
    case OPENA:
      display_dialogue();
      EZ_SetWidgetCallBack(file_entry,Load_Annotated_File, NULL);
      break;
    case NEWF:
      printf("Before Clear\n TP table\n");
/*      print_tp_ht();*/
      printf("Bitmap Table\n");
/*      print_bitmap_ht();*/
      EZ_TextClear(textW);
      printf("After Clear\n TP Table\n");
/*      print_tp_ht();*/
      printf("Bitmap Table\n");
/*      print_bitmap_ht();*/
      break;
    case SAVE:
      open_regular_file();
      break;
    case SAVEA:
      display_dialogue();
      EZ_SetWidgetCallBack(file_entry, Save_Annotated_File, NULL);
      break;
    case EXIT:
      clean_exit();
      break;
    default:
      break;
    }
}
/**************************************************************************/
int _test_ = 0;
main(ac, av) int ac; char **av;
{
  EZ_Widget *tmp, *tmpa, *mbar;
  EZ_Widget *fileM, *editM, *fcolorM, *bcolorM, *fontM;
  int       i;
  char      str[32];

  EZ_Initialize(ac,av,1);
  EZ_SetGlobalBackground("bisque2");
  EZ_DisableSliderDepression();

  /* Menu File */
  fileM = EZ_CreatePopupMenu("File");
  tmp = EZ_CreateMenuNormalButton(fileM, "Open Regular File",0, OPEN);
  tmp = EZ_CreateMenuNormalButton(fileM, "Open Annotated File",1, OPENA);
  tmp = EZ_CreateMenuNormalButton(fileM, "New", 0, NEWF);
  tmp = EZ_CreateMenuNormalButton(fileM, "Save Text", 0,  SAVE);
  tmp = EZ_CreateMenuNormalButton(fileM, "Save Annotated Text",5,SAVEA);
  tmp = EZ_CreateMenuNormalButton(fileM, "Exit",0, EXIT);
  EZ_SetWidgetCallBack(fileM, fileMCallback, NULL);

  /* Menu F_color, B_color, font. They are used as submenus */
  fcolorM = EZ_CreatePopupMenu("Set Region foreground");
  EZ_SetWidgetCallBack(fcolorM, fcolorMCallback, NULL);
  for(i = 0; i < NCOLORS; i++)
    {
      tmp = EZ_CreateMenuNormalButton(fcolorM, colors[i], -1, i);
      sprintf(str, "Ctrl-%c", *colors[i]);
      EZ_ConfigureWidget(tmp, EZ_SHORTCUT_KEY, str,0);
    }
  bcolorM = EZ_CreatePopupMenu("Set Region background");
  EZ_SetWidgetCallBack(bcolorM, bcolorMCallback, NULL);
  for(i = 0; i < NCOLORS; i++)
    {
      tmp = EZ_CreateMenuNormalButton(bcolorM, colors[i], -1, i);
      sprintf(str, "Ctrl-%c", *colors[i]);
      EZ_ConfigureWidget(tmp, EZ_SHORTCUT_KEY, str,0);
    }

  /* menu font */
  fontM = EZ_CreatePopupMenu("Set Region Font");
  EZ_SetWidgetCallBack(fontM, fontMCallback, NULL);
  for(i = 0; i < NFONTS; i++)
    {
      tmp = EZ_CreateMenuRadioButton(fontM, fonts[i], -1, 2, i, i);
      EZ_ConfigureWidget(tmp, EZ_TEXT_LINE_LENGTH, 80, 0);
    }

  /* menu Edit */
  editM = EZ_CreatePopupMenu("Edit");
  tmp = EZ_CreateMenuSubMenu(editM, "Set Region Foreground",11);
  EZ_SetSubMenuMenu(tmp, fcolorM);
  tmp = EZ_CreateMenuSubMenu(editM, "Set Region Background",11);
  EZ_SetSubMenuMenu(tmp, bcolorM);
  tmp = EZ_CreateMenuSubMenu(editM, "Set Region Font",14);
  EZ_SetSubMenuMenu(tmp, fontM);
  tmp = EZ_CreateMenuSeparator(editM);
  tmp = EZ_CreateMenuNormalButton(editM, "Underline Region", 0, 0);
  EZ_SetWidgetCallBack(tmp, underline_region, NULL);
  tmp = EZ_CreateMenuNormalButton(editM, "Replace Region By Bitmap", 0, 1);
  EZ_SetWidgetCallBack(tmp, replace_callback, NULL);
  tmp = EZ_CreateMenuSeparator(editM);
  tmp = EZ_CreateMenuNormalButton(editM, "Clear Region Text Property", 0, 1);
  EZ_SetWidgetCallBack(tmp, clear_region_tprop, NULL);


  /* badc =  EZ_CreateSimpleMenu("|whatever |||||||||||%tThis is a test|",NULL);*/

  tp_frame = EZ_CreateFrame(NULL,                          /* toplevel widget */
			    NULL
			   );
  EZ_ConfigureWidget(tp_frame, 
		     EZ_STACKING,  EZ_VERTICAL,
		     EZ_PADY,      0,
		     EZ_WIDTH,     650, EZ_HEIGHT, 500,
		     EZ_FILL_MODE, EZ_FILL_BOTH,
		     0);
  
  mbar = EZ_CreateFrame(tp_frame, NULL);
  EZ_ConfigureWidget(mbar, 
		     EZ_PADX,         0,
		     EZ_PADY,         0,
		     EZ_EXPAND,       True, 
		     EZ_HEIGHT,       0,
		     EZ_STACKING,     EZ_HORIZONTAL_LEFT,
		     0);  

  tmp = EZ_CreateMenuButton(mbar, "File", 0);
  EZ_SetMenuButtonMenu(tmp, fileM);
  tmp = EZ_CreateMenuButton(mbar, "Edit", 0);
  EZ_SetMenuButtonMenu(tmp, editM);

  tmpa = EZ_CreateFrame(tp_frame, NULL);
  EZ_ConfigureWidget(tmpa, 
		     EZ_FILL_MODE, EZ_FILL_BOTH,          /* expand children to fit in exactly  */
		     EZ_IPADX,     10,                    /* h spacing between children widgets */
		     0);
  
  textW = EZ_CreateTextWidget(tmpa, 1,1,1);              /* the text widget             */
  EZ_DisableImageDithering();
  EZ_ConfigureWidget(textW,
		     EZ_BACKGROUND, "bisque2",
		     EZ_IMAGE_FILE, "brick1.gif",         /* background tile */
		     EZ_PROPAGATE, 0,
		     EZ_EMBEDER, 1,
		     EZ_TEXT_BACKGROUND, "#af7f7f",
		     EZ_SELECTION_BACKGROUND, "#00afaf",		     
		     0);

  tmpa = EZ_CreateFrame(tp_frame, NULL);
  EZ_ConfigureWidget(tmpa,  EZ_HEIGHT, 0, 0);

  EZ_DisplayWidget(tp_frame);                              /* display the toplevel widget */ 
  EZ_FreezeWidget(textW);
  Load_CSRC_File("csrc.c"); 
  EZ_UnFreezeWidget(textW);
  while(cont) EZ_WaitAndServiceNextEvent();
  
  EZ_Shutdown();
  exit(0);
}

/*********************************************************************************************/
#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(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;
		}
	    }
	}
    }
}
		    
		  

      
      
