
/* editarea.c - part of asedit program */
/*
 * 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 <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include <Xm/PanedW.h>

#include <Xm/XmP.h>	/* needed for declaration of _XmSelectColorDefault (prcatically needed only since Motif 1.2x) */

#include "asedit.h"

/*****************************  CreateScrolledText  **************************
**
**	Create Scrolled Text widget and set the colour of recessed windows.
*/
#ifdef _NO_PROTO
static Widget CreateScrolledText (parent, wrap_on)
	Widget parent;
	Boolean wrap_on;
#else  /* ! _NO_PROTO */

static Widget CreateScrolledText (Widget parent, Boolean wrap_on)
#endif
{
	Arg		al[10];		/*  arg list		*/
	register int	ac;		/*  arg count		*/
	Pixel		foreground;	/* used for a proper set up of mono screens */
	Widget		text;

	/* create scrolled text widget */
	ac = 0;
	XtSetArg (al[ac], XmNresizeWidth, False);  ac++;
	XtSetArg (al[ac], XmNresizeHeight, False);  ac++;
	XtSetArg (al[ac], XmNscrollVertical, True);  ac++;
	XtSetArg (al[ac], XmNscrollHorizontal, !wrap_on);  ac++;
	XtSetArg (al[ac], XmNwordWrap, wrap_on);            ac++;
	XtSetArg (al[ac], XmNeditMode, XmMULTI_LINE_EDIT);  ac++;

	text = XmCreateScrolledText (parent, "edit_text", al, ac);

	/* add value changed callback  - we do not use that now
	   XtAddCallback (text, XmNvalueChangedCallback,
			(XtCallbackProc)TextCB, (XtPointer)NULL); 
	   (if ever start usign that again look out for mk_asdat !!  ***/

	/* add the focus callback to recognize which one of two text widgets
	   is currently being used to edit the text*/
	XtAddCallback (text, XmNfocusCallback,
			(XtCallbackProc)TextCB, mk_asdat(0) );

        /* add gain/losePrimary callbacks (used to set sensitivities
           in the edit and tools menus) */
        XtAddCallback (text, XmNlosePrimaryCallback,
                        (XtCallbackProc)TextCB, mk_asdat(0) );
        XtAddCallback (text, XmNgainPrimaryCallback,
                        (XtCallbackProc)TextCB, mk_asdat(0) );

	/* add modify verify callback (may be used to check changes) */
	XtAddCallback (text, XmNmodifyVerifyCallback,
			(XtCallbackProc)TextCB, mk_asdat(0) );
	/* add motion callback */
	XtAddCallback (text, XmNmotionVerifyCallback,
			(XtCallbackProc)TextCB, mk_asdat(0) );
	/* add the help callback - TEMP we use XTEXT_HELP as a call data */
	XtAddCallback (text, XmNhelpCallback,
			(XtCallbackProc)HelpCB, mk_asdat(HTEXT_HELP) );

	/* get the standard colours of the scrolled background */
	ac = 0;
	XtSetArg(al[ac], XmNbackground, &text_edit_background);	ac++;
	XtSetArg(al[ac], XmNforeground, &foreground);		ac++;
	XtGetValues(text, al, ac);

	if(lstr.useOldColorSetup)
	{
	    text_read_only_background = text_edit_background;

	    /*	Set colours of recessed widgets (text & scrollbars)
		We are doing that only for screens supporting more than 16
		colours (theoritically it should be done if the colour
		display is available, but practically if we have less than 16
		colours all of them probably have been already used up
		and the nearest available colour which will be assigned
		maybe inappropriate )*/

	    if (DefaultDepthOfScreen(XDefaultScreenOfDisplay(display)) > 4)
	    {
		Widget 		scrolled_window;
		Widget		hsbar, vsbar;	/*  ScrollBars		*/
		XrmValue		pixel_data;

		scrolled_window = XtParent(text);
		ac = 0;
		if(!wrap_on)
		    XtSetArg (al[ac], XmNhorizontalScrollBar, &hsbar);	ac++;
		XtSetArg (al[ac], XmNverticalScrollBar, &vsbar);	ac++;
		XtGetValues (scrolled_window, al, ac);	/* get scroll bars .. */

		/* get a colour to be used for editable text widgets and remember it */
		_XmSelectColorDefault (scrolled_window, 0 , &pixel_data);
		text_edit_background = *((Pixel *) pixel_data.addr);

		/* now check if the text_edit_background is not by chance identical
		   with the foreground (it happens on mono screens or for a black/white
		   setup); if so do not apply it, but use the standard background.
		*/
		if(text_edit_background == foreground)
		    text_edit_background = text_read_only_background;

		XtSetArg (al[0], XmNbackground, text_edit_background);

		/* XtSetValues (text, al, 1);  -  do not set it now; if the text
		is editable this colour will be assigned when a file is read in */
		if(!wrap_on)
		    XtSetValues (hsbar, al, 1);
		XtSetValues (vsbar, al, 1);
	    }
	}   /* useOldColorSetup */
	else
	{
	    /* all colours are set via resources; we've already stored the current
	       text widget background as the text_edit_background;
	       as the text_read_only_background use  the value from
	       the user resources: lstr.readOnlyBackground (we don't
	       use it directly to use alternatively the Old color setup)
	    */
	    text_read_only_background = lstr.readOnlyBackground;
	}

	return(text);

} /* CreateScrolledText */


/*****************************  CreateEditWorkArea  *************************
   create work area form. Inside the form there will be pane widget (with two
   scrolled text widget) and status line (bottom_row)
   The status line and one of the text widget might be unmanaged using
   Options menu.
*/
#ifdef _NO_PROTO
Widget CreateEditWorkArea(win, parent)
	aseditWindowStruct *win;
	Widget parent;
#else  /* ! _NO_PROTO */

Widget CreateEditWorkArea(aseditWindowStruct *win, Widget parent)
#endif
{

	Widget		form_work;		/* form for the work area */
	Widget		form_frame_bottom;	/* to envelope frame_bottom; needed for
						   proper management when frame_bottom is unmanaged/managed */
	Widget		row_column;	 	/*  RowColumn		*/
	Widget		pane;			/*  Pane		*/
	Widget 		wline,  wcolumn;

	Arg		al[10];			/*  arg list		*/
	register int	ac;			/*  arg count		*/
	Dimension	height;



	/*	Create a form widget for the work area */
	ac = 0;

	form_work = XtCreateWidget("form_work", xmFormWidgetClass,
		parent, al, ac);
	/*	Create paned window. 	*/

	ac = 0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNrightAttachment,   XmATTACH_FORM); ac++;
	/* bottom attachement will be set when the bottom_row widget is available ... */

	pane = XtCreateWidget ("pane", xmPanedWindowWidgetClass,
		form_work, al, ac);

	/*	Create Text (1) inside a pane	*/
	/** wrap_in_AS_COM_only: win->edit_text1 = CreateScrolledText (pane, False); **/
	win->edit_text1 = CreateScrolledText (pane, lstr.defaultWrap);
	XtManageChild (win->edit_text1);

#  if (XmVersion == 1000)
	XmAddTabGroup(win->edit_text1);
#  endif

	XtSetSensitive(win->edit_text1, False);

	/* set initial value for edit_text .... */
	win->edit_text = win->edit_text1;

	/* get the default font list ... */
	ac=0;
	XtSetArg(al[ac], XmNfontList, &default_fontlist);  ac++;
	XtGetValues(win->edit_text1, al, ac);




	XtManageChild(pane);


	/* create a frame for the bottom row of edit informations ... */

	ac = 0;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM);    ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM);    ac++;
	XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM);    ac++;

	form_frame_bottom = XmCreateForm(form_work, "form_frame_bottom", al, ac);

	ac = 0;
	/* since ver. 1.27 shadowType $ shadowThickness are set in the
	   application resource file (to support SGI schemes idea)
		XtSetArg (al[ac], XmNshadowThickness, 2);  ac++;
		XtSetArg (al[ac], XmNshadowType, XmSHADOW_IN);  ac++;
	*/

	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_FORM);    ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM);    ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM);    ac++;
	XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM);    ac++;

	win->frame_bottom = XmCreateFrame (form_frame_bottom, "frame_bottom_row", al, ac);


	/* create an XmRowColumn widget containing 5 XmLabelwidgets */
	ac = 0;
	XtSetArg (al[ac], XmNadjustLast, False);  ac++;   /* to stop stretching
						of the last widget */

	XtSetArg(al[ac], XmNorientation, XmHORIZONTAL);	ac++;
	XtSetArg(al[ac], XmNnumColumns, 1);	ac++;	/* for horizontal design it is == 1 row */

	row_column = XmCreateRowColumn (win->frame_bottom, "bottom_row", al, ac);

	ac = 0;
	win->changes_status = XmCreateLabel (row_column, " ", al, ac); /* 1 space */
	XtManageChild (win->changes_status);

	ac = 0;
	wline =	XmCreateLabel (row_column, "line", al, ac);
	XtManageChild (wline);

	ac = 0;
	win->line_number = XmCreateLabel (row_column, "1    ", al, ac); /* space
					reserved for numbers as big as: "99999"
					plus a leading and trailing space */

	XtManageChild (win->line_number);

	ac = 0;
	wcolumn =   XmCreateLabel (row_column, "column", al, ac);
	XtManageChild (wcolumn);

	ac = 0;
	win->column_number =   XmCreateLabel (row_column, "1   ", al, ac);  /* space
					reserved for numbers as big as: "9999"
					plus a leading and trailing space */
	XtManageChild (win->column_number);

	XtManageChild (row_column);


	/* now manage the bottom frame  ... */
	XtManageChild (win->frame_bottom);


	XtManageChild (form_frame_bottom);


	/* now we can set the attachement for the pane widget */
	ac = 0;
	XtSetArg(al[ac], XmNbottomAttachment,   XmATTACH_WIDGET);  ac++;
	XtSetArg(al[ac], XmNbottomWidget,     form_frame_bottom);    ac++;
	XtSetValues(pane, al, ac);

	XtManageChild(form_work);	/* now manage the manager widget */

	return(form_work);


} /* CreateEditWorkArea */
