#include "LYCurses.h"
#include "HTUtils.h"
#include "LYUtils.h"
#include "LYStructs.h"  /* includes HTForms.h */
#include "LYStrings.h"
#include "LYGlobalDefs.h"

PRIVATE int form_getstr PARAMS((struct link * form_link));

PUBLIC int change_form_link ARGS4(struct link *, form_link, int, mode, 
				document *,newdoc, BOOLEAN *,refresh_screen)
{

    FormInfo *form = form_link->form;
    int inum;
    char *tmptr;
    int c=0;

    /* move to the link position */
    move(form_link->ly, form_link->lx);

    switch(form->type) {
	case F_CHECKBOX_TYPE:
	    if(form->num_value) {
		form_link->hightext = unchecked_box;
		form->num_value = 0;
	    } else {
		form_link->hightext = checked_box;
		form->num_value = 1;
	    }
    		/* add the new info */
    	    addstr(form_link->hightext);
	    break;

	case F_RADIO_TYPE:
		/* radio buttons must have one and
		 * only one down at a time! 
		 */
	    if(form->num_value) {
		statusline("One radio button must be checked at all times!");
		sleep(2);

	    } else {	
		/* will unselect other button and select this one */
		HText_activateRadioButton(form);
		*refresh_screen = TRUE; 
	    }
	    break;

	case F_TEXT_TYPE:
	case F_PASSWORD_TYPE:
	    c = form_getstr(form_link);
	    if(form->type == F_PASSWORD_TYPE) 
        	form_link->hightext = STARS(strlen(form->value));
	    else
	    	form_link->hightext = form->value;
	    break;

	case F_RESET_TYPE:
	    HText_ResetForm(form);
            *refresh_screen = TRUE;
	    break;
	
	case F_SUBMIT_TYPE:
		/* returns new document URL */
	    newdoc->address = (char *)HText_SubmitForm(form);
	    break;

    }

    switch(c) {
	case UPARROW:
	    return(-1);

	case DNARROW:
	case       9: /* tab */
	    return(1);

	default:
	    return(0);
    }

} 

#ifdef getyx
#define GetYX(y,x)   getyx(stdscr,y,x)
#else
#define GetYX(y,x)   y = stdscr->_cury, x = stdscr->_curx
#endif

PRIVATE int form_getstr ARGS1(struct link *, form_link)
{
     FormInfo *form = form_link->form;
     int pointer = 0, tmp_pointer=0;
     int ch;
     int last_char, len;
     int max_length = (form->maxlength ? form->maxlength : 1024);
     char inputline[1024];
     int str_size = strlen(inputline);
     int startcol, startline;
     int cur_col, far_col;
     BOOLEAN extend=TRUE; /* TRUE to enable line extention */
     BOOLEAN line_extended=FALSE;  /* TRUE if the line was moved to accomadate
				    * more text entry
				    */

     /* get the initial position of the curser */
     GetYX(startline, startcol);

     /* clear the old string */
     for(ch=0; form_link->hightext[ch]; ch++) 
	addch(' ');
     /* go back to the initial position */
     move(startline, startcol);

     if(startcol + form->size > COLS-1)
	far_col = COLS-1;
     else
	far_col = startcol + form->size;

	/* if there is enough room to fit the whole
	 * string then disable the moving text feature
	 */
     if(form->maxlength && (far_col-startcol) >= form->maxlength)
	extend=FALSE;

     strcpy(inputline, form->value);

     /* find that last char in the string that is non-space */
     last_char = strlen(inputline)-1;
     while(isspace(inputline[last_char])) last_char--; 
     inputline[last_char+1] = '\0';

top:
     /*** Check to see if there's something in the inputline already ***/
     len = strlen(inputline);
     if(extend && len+startcol+5 > far_col) {
	pointer = (len - (far_col - startcol)) + 10;
	line_extended = TRUE;
     } else {
	line_extended = FALSE;
     }
     if(pointer > len)
	pointer = 1;
     
     cur_col = startcol;
     while (inputline[pointer] != '\0') {
	  if(form->type == F_PASSWORD_TYPE)
	     addch('*');
	  else
	     addch(inputline[pointer]);
	  pointer++;
	  cur_col++;
     }
     refresh();

     for (;;) {
	  ch = LYgetch();

	  switch (ch) {

#ifdef AIX
          case '\227':
#endif
	  case '\n':
	  case '\r':
	  case '\t':
	  case DNARROW:
	  case UPARROW:
	       inputline[pointer] = '\0';
    	       StrAllocCopy(form->value, inputline);
		/* fill out the rest of the space with spaces */
	       for(;cur_col<far_col;cur_col++)
		  addch(' ');
	       return(ch);
	       break;

          /* Control-G aborts */
          case 7:
               return(-1);

	 	/* break */  /* implicit break */


	  /* erase all the junk on the line and start fresh */
	  case 21 :
		move(startline, startcol);
		clrtoeol();
		pointer = 0;  /* clear inputline */
		cur_col = startcol;
		line_extended = FALSE;
		refresh();
		break;

	  /**  Backspace and delete **/

	  case '\010':
	  case '\177':
	  case LTARROW:
	       if (pointer > 0) {
		    addch('\010');
		    addch(' ');
		    addch('\010');
	       
		    pointer--;
		    cur_col--;

		    if(line_extended && cur_col+15 < far_col) {
     			if(pointer + startcol+5 > far_col) {
			    tmp_pointer = (pointer - (far_col - startcol)) + 5;
			    if(tmp_pointer < 0) tmp_pointer=0;
			} else {
			    tmp_pointer = 0;
			    line_extended = FALSE;
			}

			move(startline, startcol);
			clrtoeol();
		
			cur_col = startcol;
     
     			while (tmp_pointer != pointer) {
	  			addch(inputline[tmp_pointer]);
	  			tmp_pointer ++;
	  			cur_col++;
     			}
			
		    }
		    refresh();

	       } else if(ch == LTARROW) {
		   inputline[0] = '\0';
    		   StrAllocCopy(form->value, inputline);
		   return(ch);
	       }
	       break;
		    
	       
	  default:
	       if (printable(ch) && pointer < max_length) {
		    inputline[pointer++]= ch;
		    cur_col++;
		    if(form->type == F_PASSWORD_TYPE)
		 	addch('*');
		    else
		    	addch(ch);

		    if(extend && cur_col+2 > far_col) {
			tmp_pointer = (pointer - (far_col - startcol)) + 10;
			if(tmp_pointer > pointer)
			    tmp_pointer = 1;
			line_extended = TRUE;

			move(startline, startcol);
			clrtoeol();
     
			cur_col = startcol;

     			while (tmp_pointer != pointer) {
	  			addch(inputline[tmp_pointer]);
	  			tmp_pointer ++;
	  			cur_col++;
     			}
			
		    } else if(pointer >= max_length) {
			statusline("Maximum length reached!");
			inputline[pointer] = '\0';
			move(startline,startcol);
		  	pointer=0;
			/* go back to to top and print it out again */
			goto top;
		    }
		    refresh();
	       }
	       /* else
	          return(ch); */
		/* just ignore unprintable charactors */
	  }
     }

}
