/*********************************************************************/
/* file: highlight.c - functions related to the highlight command    */
/*                             TINTIN ++                             */
/*          (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t             */
/*                     coded by Bill Reiss 1993                      */
/*********************************************************************/
#include <string.h>
#include "tintin.h"

#if IRIX
  #include <stdlib.h>
  #include <unistd.h>
#endif

extern char *get_arg_in_braces();
extern struct listnode *searchnode_list();
extern struct listnode *search_node_with_wild();

void add_codes();

extern struct listnode *common_highs;
extern char vars[10][BUFFER_SIZE]; /* the %0, %1, %2,....%9 variables */
extern int hinum;
extern int mesvar[6];
extern char high_starts[13][80];
extern char high_ends[13][80];

/***************************/
/* the #highlight command  */
/***************************/
void parse_high(arg, ses)
     char *arg;
     struct session *ses;
{
  char left[BUFFER_SIZE], right[BUFFER_SIZE], result[BUFFER_SIZE];
  struct listnode *myhighs, *ln;
  int colnum, colflag;
  char *pright;
  pright=right;
  *pright='\0'; 
  myhighs=(ses) ? ses->highs : common_highs;
  arg=get_arg_in_braces(arg, left, 0);
  arg=get_arg_in_braces(arg, right, 1);
  colflag=FALSE;
  if(!*left) {
    tintin_puts("#THESE HIGHLIGHTS HAVE BEEN DEFINED:", ses);
    show_list(myhighs);
    prompt(ses);
  }


  else {
    if (sscanf(left,"%d",&colnum)!=0) {
      if ((colnum<1 || colnum>8) && mesvar[4])  
        tintin_puts2("#Invalid color argument, must be between 1 and 8.",ses);
      else
        colflag=TRUE;
    }
    else {
      if (is_abrev(left,"bold") || is_abrev(left,"reverse") || is_abrev(left,"blink") || is_abrev(left,"italic") || is_abrev(left,"faint"))
        colflag=TRUE;
      else 
        if (mesvar[4])
          tintin_puts2("#Invalid argument, must be blink, bold, faint, italic, reverse, or 1-8",ses);
    }    
    if (colflag==TRUE) {

      if((ln=searchnode_list(myhighs, right))!=NULL)
        deletenode_list(myhighs, ln);
      insertnode_list(myhighs, right, left);
      hinum++;
      if (mesvar[4]) {
        sprintf(result, "#Ok. {%s} is now highlighted %s.", right, left);
        tintin_puts2(result, ses);
      }
    }
  }  
}


/*****************************/
/* the #unhighlight command */
/*****************************/

void unhighlight_command(arg, ses)
     char *arg;
     struct session *ses;
{
  char left[BUFFER_SIZE] ,result[BUFFER_SIZE];
  struct listnode *myhighs, *ln, *temp;
  int flag;
  flag=FALSE;
  myhighs=(ses) ? ses->highs : common_highs;
  temp=myhighs;
  arg=get_arg_in_braces(arg,left, 1);
  while ((ln=search_node_with_wild(temp, left))!=NULL) {
    if (mesvar[4]) {
      sprintf(result, "Ok. {%s} is no longer %s.", ln->left, ln->right);
      tintin_puts2(result, ses);
    }
    deletenode_list(myhighs, ln);
    flag=TRUE;
    temp=ln;
  }
  if (!flag && mesvar[4])
    tintin_puts2("#THAT HIGHLIGHT IS NOT DEFINED.", ses);
}


void do_one_high(line, ses)
     char *line;
     struct session *ses;
{
  /* struct listnode *ln, *myhighs; */
  struct listnode *ln;
  char temp[BUFFER_SIZE],temp2[BUFFER_SIZE],result[BUFFER_SIZE];
  char *lptr, *tptr, *line2, *firstch_ptr;
  char *place;
  int hflag,length;
  hflag=TRUE;
  ln=ses->highs;
  while ((ln=ln->next)) {

      if(check_one_action(line,ln->left, ses)) {
        firstch_ptr=ln->left;
        if (*(firstch_ptr)=='^')
          firstch_ptr++;          
        prepare_actionalias(firstch_ptr, temp, ses);
	*(line+strlen(line)+2)='\0';
	hflag=TRUE;
	line2=line;
	while(hflag) {
	  lptr=temp;
          place=line2;
          while(*lptr!=*line2) {
            place=++line2;
          }
          length=0;
	  while(*lptr==*line2 && *lptr!='\0') {
            length++;
	    lptr++;
	    line2++;
	  }
	  if (length>=strlen(temp))
	      hflag=FALSE;
	}
	add_codes(temp,temp2,ln->right,0);
	*(place)='\0';
        tptr=line2;
        sprintf(result,"%s%s%s",line,temp2,tptr);
        strcpy(line,result);
	}
  }
}
void add_codes(line, result, htype, flag)
     char *line;
     char *result;
     char *htype;
     int flag;
{
  int colnum, highnum;
  highnum=-1;
  if (sscanf(htype,"%d",&colnum)==0) {
    if (is_abrev(htype,"bold"))
      highnum=1;
    else if (is_abrev(htype,"reverse")) 
      highnum=0;
    else if (is_abrev(htype,"blink")) 
      highnum=2;
    else if (is_abrev(htype,"italic")) 
      highnum=3;
    else if (is_abrev(htype,"faint")) 
      highnum=4;
    else if (is_abrev(htype,"none"))
      highnum=13;
  }
  else 
      highnum=colnum+4;
  if (highnum==-1 || (highnum==13 && flag==0)) {
    tintin_puts2("#Error in highlight type.", (struct session *)NULL);
    return;
  }
  if (highnum!=13)
    strcpy(result,high_starts[highnum]);
  else 
    strcpy(result,high_ends[0]);
  if (flag==0) {
    strcat(result,line);
    strcat(result,high_ends[highnum]);
  }
}