 /*
  * Khoros: $Id: work.c,v 1.1 1991/05/10 15:58:12 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: work.c,v 1.1 1991/05/10 15:58:12 khoros Exp $";
#endif

 /*
  * $Log: work.c,v $
 * Revision 1.1  1991/05/10  15:58:12  khoros
 * Initial revision
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER 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 PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "composer.h"

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>         File Name: work.c
 >>>>
 >>>>      Program Name: composer
 >>>> 
 >>>> Date Last Updated: Tue Jun  5 19:30:58 1990
 >>>>
 >>>>          Routines: get_pane() - reads ui spec from a file into list
 >>>> 		 	put_pane() - writes interanl list ui spec to a file
 >>>> 		 	get_prog() - reads prog spec from a file
 >>>> 		 	put_prog() - writes internal prog spec to a file
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/





/********************************************************
*
*  Routine Name:  get_pane()
*       Purpose:  Read a user interface spec from a file. Verifies that
*		  it is a single pane and puts it into a 2d character array.
*         Input:  pane_file	- a file name used for the pane_file
*        Output:  gui_spec	- a global 2d character array containing pane 
				spec
		  returns 1 upon success, 0 on failure
*     Called By:  run_Composer() and main()
*
	NOTE:  This is basically a modified version of xvf_create_form()
	written by Mark Young & Danielle Argiro

********************************************************/

int
get_pane(pane_file)
char 	*pane_file;	/* name of spec file 		*/
{
	FILE		*file;
	char		*fullpath, temp[MaxLength], **xvf_read_database();
	int 	        i, count=0, line_num, db_size; 

	fullpath = vfullpath(pane_file, NULL, NULL); 
	if (!(file = fopen(fullpath, "r"))) {
           (void) sprintf(temp, "Unable to open '%s' to read pane specification", pane_file);
           xvf_error_wait(temp, "COMPOSER WARNING!", "OK");
           return(0);
        }

	if (gui_spec != NULL)  xvf_free_database(gui_spec);

	gui_spec = xvf_read_database(file, &line_num, &db_size);
	if (gui_spec == NULL) {
	   fclose(file);
	   return(0);
	}

	gui_spec_lines = line_num;   /* set global number of lines in spec */

	for (i=0; i<line_num; i++) {
	    if (xvf_get_line_type(gui_spec[i]) == StartPane) count++; 
	}

	if (count > 1) {
           (void) sprintf(temp, "This specification file has '%d' panes but only one is allowed!", count);
           xvf_error_wait(temp, "COMPOSER WARNING!", "OK");
           return(0);
	}

	fclose(file);
	return(1);
}  


/********************************************************
*
*  Routine Name:  put_pane()
*       Purpose:  Write a user interface spec from the internal array to
*		  a file.
*         Input:  gui_spec	- a gloabal character array containing pane spec
*        Output:  pane_file	- a file name used for the pane_file
		  returns 1 upon success, 0 on failure
*     Called By:  run_Composer() and main()
*
********************************************************/

#define BOTTOM 10000

int
put_pane(pane_file)
char 	*pane_file;	/* name of specification file	*/
{
	FILE		*file;
        char    	warning[MaxLength];
        char    	**xvf_copy_database(), **spec;
	char		*fullpath, temp[MaxLength];
	int 	        j, start, i; 
	int		min_y, min_line;
	int		in_C, do_C, line_C;
	int		in_T;
	int		done;
	Line_Info	line_info;

	fullpath = vfullpath(pane_file, NULL, NULL); 
	if (!(file = fopen(fullpath, "w"))) {
           (void) sprintf(temp, "Unable to open '%s' to write pane specification", pane_file);
           xvf_error_wait(temp, "COMPOSER WARNING!", "OK");
           return(0);
        }

        spec = xvf_copy_database(gui_spec);
        if (spec == NULL) {
            (void) sprintf(warning, "Unable to copy user interface specification");
            xvf_error_wait(warning, "COMPOSER WARNING!", "OK");
            return(0);
        }


	/* order the lines according to the y_offset from top to bottom */

	/* first, verify that the beginning 3 lines are correct */

	(void) sprintf(warning, "User interface specification is corrupted. You may be able to fix what was written using a text editor.");
	j = 0;
	if (xvf_get_line_type(spec[j]) == StartForm) {
	    fputs(spec[j], file); fputs("\n", file);
	}
	else {
	    xvf_error_wait(warning, "COMPOSER WARNING!", "OK");
	}
	j++;
	if (xvf_get_line_type(spec[j]) == StartSubForm) {
	    fputs(spec[j], file); fputs("\n", file);
	}
	else {
	    xvf_error_wait(warning, "COMPOSER WARNING!", "OK"); 
	}
	j++;
	if (xvf_get_line_type(spec[j]) == StartPane) {
	    fputs(spec[j], file); fputs("\n", file);
	}
	else {
	    xvf_error_wait(warning, "COMPOSER WARNING!", "OK"); 
	}
	j++;
	start=j;

	/* find minimum y position of lines */
	in_C = do_C = FALSE; 
	in_T = FALSE; 
	done = FALSE; 
	while ( !done) {
	    min_y = BOTTOM;
	    for (j = start; j < gui_spec_lines -3; j++) {
	        xvf_clear_line_info(&line_info);
	        xvf_gen_parse(spec[j], &line_info);
		if (line_info.typeflag == MutExcl) in_C = TRUE;
		if (line_info.typeflag == MutExcl && do_C != TRUE) line_C = j;
		else if (line_info.typeflag == Toggle) {
		    in_T = TRUE;
		}
		if (line_info.typeflag == End && in_C == TRUE)  in_C = FALSE;
		if (line_info.typeflag == Blank) {
	            if (line_info.ypos < min_y) {
		        min_line = j; min_y = line_info.ypos;
		        if (in_C == TRUE) do_C = TRUE; 
			else do_C = FALSE;
	            }
		} 
		else if (line_info.typeflag != MutExcl
                       && line_info.typeflag != End) {
	            if (line_info.y < min_y) {
		        min_line = j; min_y = line_info.y;
		        if (in_C == TRUE) do_C = TRUE; 
			else do_C = FALSE;
	            }
		}
		if (in_T == TRUE) {  /* skip past all lines in toggle */
		    for(j; line_info.typeflag != End; j++) {
		        xvf_clear_line_info(&line_info);    
			xvf_gen_parse(spec[j], &line_info);
		    }
		    j--; in_T = FALSE;
		}
	    }
	    if (min_y == BOTTOM) {
	        done = TRUE;
	    }
	    else if (xvf_get_line_type(spec[min_line]) == Toggle) {
		line_info.typeflag = Toggle;
		for (i = min_line; line_info.typeflag != End; i++){
		    fputs(spec[i], file); fputs("\n", file);
	            /* mark the line printed as if at the bottom */
		    xvf_clear_line_info(&line_info);
	            xvf_gen_parse(spec[i], &line_info);
	            if (line_info.typeflag == Blank) line_info.ypos = BOTTOM+1;
	            else line_info.y = BOTTOM+1;
	            xvf_gen_deparse(&line_info, spec, i);
		}
	    }
	    else if (do_C == TRUE) {
		line_info.typeflag = MutExcl;
		for (i = line_C; line_info.typeflag != End; i++){
		    fputs(spec[i], file); fputs("\n", file);
	            /* mark the line printed as if at the bottom */
		    xvf_clear_line_info(&line_info);
	            xvf_gen_parse(spec[i], &line_info);
	            if (line_info.typeflag == Blank) line_info.ypos = BOTTOM+1;
	            else line_info.y = BOTTOM+1;
	            xvf_gen_deparse(&line_info, spec, i);
		}
		do_C = FALSE;
	    }
	    else {
                /* print the line */
		fputs(spec[min_line], file); fputs("\n", file);
		xvf_clear_line_info(&line_info);
		xvf_gen_parse(spec[min_line], &line_info);
	        if (line_info.typeflag == Blank) line_info.ypos = BOTTOM+1;
	        else line_info.y = BOTTOM+1;
		xvf_gen_deparse(&line_info, spec, min_line);
	    }
	}
	/* print last 3 End lines */
	j = gui_spec_lines - 3;
	if (xvf_get_line_type(spec[j]) == End) {
	    fputs(spec[j], file); fputs("\n", file);
	}
	else {
	    xvf_error_wait(warning, "COMPOSER WARNING!", "OK"); 
	}
	j++;
	if (xvf_get_line_type(spec[j]) == End) {
	    fputs(spec[j], file); fputs("\n", file);
	}
	else {
	    xvf_error_wait(warning, "COMPOSER WARNING!", "OK"); 
	}
	j++;
	if (xvf_get_line_type(spec[j]) == End) {
	    fputs(spec[j], file); fputs("\n", file);
	}
	else {
	    xvf_error_wait(warning, "COMPOSER WARNING!", "OK"); 
	}
	fclose(file);
	return(1);
}

/********************************************************
*
*  Routine Name:  get_prog()
*       Purpose:  Read a program specification from a file. Verifies that
*		  it is not corrupt and puts it into a 2d character array.
*		  Uses routines in the ghost library.
*         Input:  prog_file	- a file name used for the prog_file
*        Output:  prog_spec	- a global pointer to a 2d character array 
				containing prog spec
		  returns 1 upon success, 0 on failure
*     Called By:  run_Composer() and main()
*
********************************************************/

int
get_prog(prog_file)
char 	*prog_file;	/* name of program spec file	*/
{
	FILE		*file;
	char		*fullpath, **gw_read_progfile(), temp[MaxLength];
	char		**keynames[2];

	fullpath = vfullpath(prog_file, NULL, NULL); 
	if (!(file = fopen(fullpath, "r"))) {
           (void) sprintf(temp, 
	"Unable to open '%s' to read program specification file" , prog_file);
           xvf_error_wait(temp, "COMPOSER WARNING!", "OK");
           return(0);
        }

	gw_init_keynames(keynames);

	prog_spec = gw_read_progfile(file, keynames);
	if (prog_spec == NULL) {
	   fclose(file);
	   return(0);
	}

	fclose(file);
	return(1);
}  

/********************************************************
*
*  Routine Name:  put_prog()
*       Purpose:  Write a program specification to a file.
*		  Uses routines in the ghost library.
*        Output:  prog_file	- the file name that is written
*         Input:  prog_spec	- a global pointer to a 2d character array 
				containing prog spec
		  returns 1 upon success, 0 on failure
*     Called By:  run_Composer() and main()
*
********************************************************/

int
put_prog(prog_file)
char 	*prog_file;	/* name of program spec file	*/
{
	char		temp[MaxLength];
	char		**keynames[2];

	gw_init_keynames(keynames);

	if ( !gr_write_progfile(prog_file, prog_spec, keynames, TRUE)) {
           (void) sprintf(temp, "Unable to write the program specification '%s' file",
 			prog_file);
           xvf_error_wait(temp, "COMPOSER WARNING!", "OK");
	   return(0);
	}

	return(1);
}  
