/* calc_lc.c - calculate line and column numbers (freeware version) */

/*
 * Copyright 1991 - 1994,  Andrzej Stochniol, London, UK
 *
 * ASEDIT text editor, both binary and source (hereafter, Software) is
 * copyrighted by Andrzej Stochniol (hereafter, AS) and ownership remains
 * with AS.
 *
 * AS grants you (hereafter, Licensee) a license to use the Software
 * for academic, research and internal business purposes only, without a
 * fee.  Licensee may distribute the binary and source code (if released)
 * to third parties provided that the copyright notice and this statement
 * appears on all copies and that no charge is associated with such copies.
 *
 * Licensee may make derivative works.  However, if Licensee distributes
 * any derivative work based on or derived from the Software, then
 * Licensee will:
 * (1) notify AS regarding its distribution of the derivative work, and
 * (2) clearly notify users that such derivative work is a modified version
 *      and not the original ASEDIT distributed by AS.
 *
 * Any Licensee wishing to make commercial use of the Software should
 * contact AS to negotiate an appropriate license for such commercial use.
 * Commercial use includes:
 * (1) integration of all or part of the source code into a product for sale
 *     or license by or on behalf of Licensee to third parties, or
 * (2) distribution of the binary code or source code to third parties that
 *     need it to utilize a commercial product sold or licensed by or on
 *     behalf of Licensee.
 *
 * A. STOCHNIOL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS
 * SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
 * IMPLIED WARRANTY.  IN NO EVENT SHALL A. STOCHNIOL BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * By using or copying this Software, Licensee agrees to abide by the
 * copyright law and all other applicable laws, and the terms of this
 * license.
 * AS shall have the right to terminate this license immediately by
 * written notice upon Licensee's breach of, or non-compliance with, any
 * of its terms.  Licensee may be held legally responsible for any
 * copyright infringement that is caused or encouraged by Licensee's
 * failure to abide by the terms of this license.
 *
 *
 *      Andrzej Stochniol       (A.Stochniol@ic.ac.uk)
 *      30 Hatch Road
 *      London SW16 4PN
 *      UK
 */

#include <stdio.h>
#include <string.h>

#include <Xm/Text.h>

#include "asedit.h"

/*****************************  calc_text_lcn  *****************************
**
**	Calculates line and column numbers in the edit_text widget.
**	(called from TextCB)
*/
#ifdef _NO_PROTO
void calc_text_lcn (w, client_data, call_data)
    Widget w;
    XtPointer client_data;
    XtPointer call_data;
#else  /* ! _NO_PROTO */

void calc_text_lcn (Widget w, XtPointer client_data, XtPointer call_data)
#endif
{

      XmTextVerifyCallbackStruct  *txt_data = (XmTextVerifyCallbackStruct *) call_data;
      long pos;			/* in Motif XmTextPosition is defined as long */
      String text_buffer;
      Arg    al[2];
      int    reason;		/* reason for the callback */
      long   extra_column, extra_line, pos_mod, extra_column_ntab;

      int id                  = get_id_from_asdat(client_data);
      aseditWindowStruct *win = get_win_from_asdat(client_data);

      /* only for version which shows line and column during editing;
	 convert the current position into line and column */

      reason = txt_data->reason;
      pos = txt_data->newInsert;


      if(reason == XmCR_MODIFYING_TEXT_VALUE)	 pos = txt_data->startPos;

      /* modifying marks ..... */
      if(win->marks_used && (reason == XmCR_MODIFYING_TEXT_VALUE))
      {
	int i, len = txt_data->text->length, del_len;

	if(len <= 0)  del_len = (int) (txt_data->endPos - txt_data->startPos); /* amount of text deleted */
	for(i=0; i < TOTAL_MARKS; i++)
	{
	    if(win->mark_set[i])
	    {
		if(win->mark_pos[i] < pos)	;	/* DO Nothing */
		else
		{
		   if(len > 0)  win->mark_pos[i] +=len;		/* text adding ... */
		   else			/* check for  text deleting ... (or just replacing with
						pending delete */
		   {
			/* now check if any data is to be  deleted  */
			if(del_len > 0)
			{
			     /* text deleting ...(or just replacing with pending delete) */
			     
			    if(win->mark_pos[i] >= (pos+del_len)) win->mark_pos[i] -= del_len;
			    else win->mark_pos[i] = pos;
			}
		    }
		}
	    }
	}
      }

      /* for the MODIFYING_TEXT_VALUE  (when the text is entered) the
	increment of the column and line number will be calculated
	on the basis what text is entered;
      */
      if(reason == XmCR_MODIFYING_TEXT_VALUE && txt_data->text->length > 0)
      {

	if(txt_data->startPos != txt_data->newInsert)
	{
	    /* the text is being pasted in the place different then the current
	       line and column. Recalculate them first ...
	       (it is probably redesigned and can't happen in Motif 1.2 ...)
	    */

	}

	textPosToLineColumn(txt_data->text->ptr, (long)txt_data->text->length,
		 (long)txt_data->text->length, win->tabsize, &extra_line, &extra_column,
		 &extra_column_ntab);


	if(extra_line <= 1L)	/* there was no extra line */
		{ win->column += extra_column-1 ; win->column_ntab += extra_column_ntab-1 ; }
	else			/* there were extra lines so column value is reset */
	{
		win->column      = extra_column;
		win->column_ntab = extra_column_ntab;
		win->line       += extra_line - 1;
	}

      }
      else
      {
	long buf_size;			/* size of the text buffer */

	{
	    /* get the internally stored text  */
	    XtSetArg(al[0], XmNvalue, &text_buffer);
	    XtGetValues(w, al, 1);
	    buf_size    = (long) strlen(text_buffer);
	}

	/* search from beginning */
	textPosToLineColumn(text_buffer, buf_size, pos, win->tabsize, 
			&(win->line), &(win->column), &(win->column_ntab) );

	XtFree(text_buffer);

      }




} /* calc_text_lcn */

