/*
 * eb_design.c
 *
 * This file is part of the Easy Database. It contains the routines
 * that deal with creating new databases and changing the fields.
 *
 * Written by Mark Overmars
 *
 * Version 0.9
 * Last Changed: Sep 16, 1992
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "forms.h"
#include "eb_main.h"

/***************************** INTERNAL VARIABLES ************************/

static char newnames[MAXFIELDNUMB][MAXFIELDLENGHT]; /* New field names */
static int oldfields[MAXFIELDNUMB];		    /* Old field indices */
static int currentfield = -1;			    /* Current selected field */
static int newfieldnumb = 0;			    /* New number of fields */

/***************************** INTERNAL ROUTINES ************************/

/*********
 *  static void fillin_browser()
 *	Fills in the different field names in the browser
 *********/

static void fillin_browser()
{
    int i;
    if (currentfield > newfieldnumb) currentfield = newfieldnumb;
    if (currentfield < 0) currentfield = 0;
    if (newfieldnumb == 0) currentfield = -1;
    fl_freeze_object(ch_fieldsobj);
    fl_clear_browser(ch_fieldsobj);
    for (i=0; i<newfieldnumb; i++)
	fl_add_browser_line(ch_fieldsobj, newnames[i]);
    if (currentfield >=0)
	fl_select_browser_line(ch_fieldsobj, currentfield+1);
    fl_unfreeze_object(ch_fieldsobj);
}


/***************************** CALLBACK ROUTINES ************************/

void ch_add_cb(FL_OBJECT *obj,  long arg)
{
    int i;
    if (newfieldnumb == MAXFIELDNUMB)
    {
	fl_show_message("Cannot add another field.", "", "");
	return;
    }
    currentfield++;
    for (i=newfieldnumb; i>currentfield; i--)
	{ strcpy(newnames[i], newnames[i-1]); oldfields[i] = oldfields[i-1];}
    strcpy(newnames[currentfield], 
		fl_show_input("Give name of field to add:", ""));
    oldfields[currentfield] = -1;
    newfieldnumb++;
    fillin_browser();
}

void ch_insert_cb(FL_OBJECT *obj,  long arg)
{
    int i;
    if (newfieldnumb == MAXFIELDNUMB)
    {
	fl_show_message("Cannot add another field.", "", "");
	return;
    }
    if (currentfield < 0) currentfield++;
    for (i=newfieldnumb; i>currentfield; i--)
	{ strcpy(newnames[i], newnames[i-1]); oldfields[i] = oldfields[i-1];}
    strcpy(newnames[currentfield], 
		fl_show_input("Give name of field to insert:", ""));
    oldfields[currentfield] = -1;
    newfieldnumb++;
    fillin_browser();
}

void ch_delete_cb(FL_OBJECT *obj,  long arg)
{
    int i;
    if (currentfield < 0) return;
    newfieldnumb--;
    for (i=currentfield; i<newfieldnumb; i++)
	{ strcpy(newnames[i], newnames[i+1]); oldfields[i] = oldfields[i+1];}
    fillin_browser();
}

void ch_change_cb(FL_OBJECT *obj,  long arg)
{
    if (currentfield < 0) return;
    strcpy(newnames[currentfield], 
		fl_show_input("Give new name of field:", newnames[currentfield]));
    fillin_browser();
}

void ch_moveup_cb(FL_OBJECT *obj,  long arg)
{
    char str[MAXFIELDLENGHT];
    int old;
    if (currentfield < 1) return;
    strcpy(str, newnames[currentfield-1]);
    strcpy(newnames[currentfield-1], newnames[currentfield]);
    strcpy(newnames[currentfield], str);
    old = oldfields[currentfield-1];
    oldfields[currentfield-1] = oldfields[currentfield];
    oldfields[currentfield] = old;
    currentfield--;
    fillin_browser();
}

void ch_movedown_cb(FL_OBJECT *obj,  long arg)
{
    char str[MAXFIELDLENGHT];
    int old;
    if (currentfield < 0 || currentfield == newfieldnumb-1) return;
    strcpy(str, newnames[currentfield+1]);
    strcpy(newnames[currentfield+1], newnames[currentfield]);
    strcpy(newnames[currentfield], str);
    old = oldfields[currentfield+1];
    oldfields[currentfield+1] = oldfields[currentfield];
    oldfields[currentfield] = old;
    currentfield++;
    fillin_browser();
}

void ch_fields_cb(FL_OBJECT *obj,  long arg)
{
    currentfield = fl_get_browser(ch_fieldsobj) - 1;
}

/***************************** EXTERNAL ROUTINES ************************/

/*********
 *  void change_database_layout()
 *	Changes the layout of the database. Can also be called to create
 *	a new database layout.
 *********/
 
void change_database_layout()
{
    FL_OBJECT *obj;
    int i, j;
    char olddata[MAXFIELDNUMB][MAXFIELDLENGHT];
    char newdata[MAXFIELDNUMB][MAXFIELDLENGHT];
    char str[MAXSTRINGLENGHT];

    /* Fill in the data */
    newfieldnumb = fieldnumb;
    currentfield = 0;
    string_to_fields(database[0].data, newnames);
    for (i=0; i<fieldnumb; i++) 
	oldfields[i] = i;
    
    /* Show the form and do interaction */
    fl_deactivate_all_forms();
    fillin_browser();
    fl_show_form(changeform, FL_PLACE_CENTER, FALSE, NULL);
    do {
	obj = fl_do_forms();
    } while (obj != ch_cancelobj && obj != ch_readyobj);
    fl_hide_form(changeform);
    fl_activate_all_forms();
    if (obj == ch_cancelobj) return;
    if (newfieldnumb == 0)
    {
	fl_show_message("Cannot create a database without fields", "", "");
	return;
    }
    
    /* Change the database layout */
    fieldnumb = newfieldnumb;
    fields_to_string(newnames, str, fieldnumb);
    change_record(0, str);
    for (i=1; i<= recordnumb; i++)
    {
	string_to_fields(database[i].data, olddata);
	for (j=0; j<fieldnumb; j++)
	    if (oldfields[j] < 0)
		strcpy(newdata[j], "");
	    else
		strcpy(newdata[j], olddata[oldfields[j]]);
	fields_to_string(newdata, str, fieldnumb);
	change_record(i, str);
    }
}
