#include <stdio.h>
#include <string.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/DialogS.h>
#include <Xm/DrawingA.h>
#include <Xm/DrawnB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/List.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/ScrolledW.h>
#include <Xm/ScrollBar.h>
#include <Xm/SelectioB.h>
#include <Xm/Separator.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/ToggleB.h>
#include <Interact.h>
#include <Browser.h>
#include <xgbitmaps.h>
#include "Matrix.h"
#define INPUT           100
#define OUTPUT  101
#define UNITS           102
#define DISTANCES       103

#define NCOLS 10
Widget theContainer;
Widget          CatLabel;
Widget          ChooseThemeButton, EditAttButton, EditDBButton;
Widget          theDialog;
Widget          mainShell;
Widget          AttList;
Widget          EditTable;
Widget          *AttTexts;
Widget          *AttButtons;
Widget          *AttLabels;
XtAppContext    appContext;
Display        *display;
char          **values;
Widget          shell, edit_dialog;
Widget          Create_Edit_Dialog(), Create_Input_Cell(), Create_Output_Cell();
Widget          Create_Att_Table();
void            DoEditDialog(), CallFile(), CallInputOutput(); 
void            CallOk(), CallCancel(), CallHelp(), CallReset(), CallAccept();
void            CallEditAtt(), CallEditDB(), CallTheme();
char           *namestring = "helvb12", *zonestring = "helvb14";
Widget          inputField;
void           GetAttText(), follow_link();


static XrmOptionDescRec initTable[] = {
{"-title",	"*title",	XrmoptionSepArg, (caddr_t)"d.vect.db Table Editor"},
{"-font",	"*fontList",	XrmoptionSepArg, (caddr_t)"fixed"},
{"-fn",		"*fontList",	XrmoptionSepArg, (caddr_t)"fixed"},
};

main(argc, argv)
    int             argc;
    char           *argv[];
{
    Widget          area, dialog;
    Arg             al[30];
    int             ac;

    G_gisinit(argv[0]);
    mainShell = shell = XtAppInitialize(&appContext, "d.vect.edit",
					initTable, XtNumber(initTable),
					&argc, argv, NULL, NULL, 0);

    AttTexts = (Widget *) G_malloc(NCOLS * sizeof(Widget));
    AttLabels = (Widget *) G_malloc(NCOLS * sizeof(Widget));
    AttButtons = (Widget *) G_malloc(NCOLS * sizeof(Widget));
    values = (char **) G_malloc(NCOLS * sizeof(char *));
    display = XtDisplay(shell);

    dialog = XmCreateRowColumn(shell, "main message", NULL, 0);
    EditAttButton = XmCreatePushButton(dialog, "View/Edit Attributes of map objects", NULL, 0);
    XtAddCallback(EditAttButton, XmNactivateCallback, CallEditAtt, NULL);
    XtManageChild(EditAttButton);

    ChooseThemeButton = XmCreatePushButton(dialog, "Specify New/Existing Theme", NULL, 0);
    XtAddCallback(ChooseThemeButton, XmNactivateCallback, CallTheme, NULL);
    XtManageChild(ChooseThemeButton);

    EditDBButton = XmCreatePushButton(dialog, "Edit the Data Base", NULL, 0);
    XtAddCallback(EditDBButton, XmNactivateCallback, CallEditDB, NULL);
    XtManageChild(EditDBButton);

    XtManageChild(dialog);
    
    XtRealizeWidget(shell);
    XtAppMainLoop(appContext);
}

void CallEditAtt(w, call_data, arg)
     Widget w;
     caddr_t call_data, arg;

{
     EditTable = Create_Edit_Dialog(w, "Table Editor");
     XtManageChild(EditTable);
}

void CallEditDB(w, call_data, arg)
     Widget w;
     caddr_t call_data, arg;
{
}

void CallTheme(w, call_data, arg)
     Widget w;
     caddr_t call_data, arg;
{
}

Widget 
Create_Edit_Dialog(parent, name)
    Widget          parent;
    char *name;
{
    Widget          attLB, done_button, cancel_button, help_button;
    Widget          CatLabelDescr ;
    Widget          assign_board;
    Arg             al[30];
    int             ac;

    ac = 0;
	XtSetArg(al[ac], XmNautoUnmanage, FALSE);
    ac++;
    theDialog = XmCreateFormDialog(parent, name, al, ac);
    /* XmRemoveTabGroup(theDialog);*/

    ac = 0;
    XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNlabelString,
             XmStringCreate(name, XmSTRING_DEFAULT_CHARSET));ac++;
    XtSetArg(al[ac], XmNx, 20);ac++;
    attLB = XmCreateLabel(theDialog, "attLB", al, ac);
    XtManageChild(attLB);

    ac = 0;
    XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNtopWidget, attLB); ac++;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
    assign_board = Create_Att_Table(theDialog, al, ac);
    XtManageChild(assign_board);

    ac = 0;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
    done_button = XtCreateManagedWidget("done", xmPushButtonWidgetClass, theDialog, al, ac);
    XtAddCallback(done_button, XmNactivateCallback, CallOk, theDialog);
    XtManageChild(done_button);

    ac = 0;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
    cancel_button = XtCreateManagedWidget("cancel", xmPushButtonWidgetClass, theDialog, al, ac);
    XtAddCallback(cancel_button, XmNactivateCallback, CallCancel, theDialog);
    XtManageChild(cancel_button);

    ac = 0;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNleftWidget, done_button); ac++;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNrightWidget, cancel_button); ac++;
    XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
    help_button = XtCreateManagedWidget("help", xmPushButtonWidgetClass, theDialog, al, ac);
    XtAddCallback(help_button, XmNactivateCallback, CallHelp, theDialog);
    XtManageChild(help_button);

    ac = 0;
    XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNbottomWidget, done_button); ac++;
    XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNtopWidget, assign_board); ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNlabelString,
             XmStringCreate("name of the object", XmSTRING_DEFAULT_CHARSET));ac++;
    CatLabelDescr = XmCreateLabel(theDialog, "cat lab descr", al, ac);
    XtManageChild(CatLabelDescr);

    ac = 0;
    XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNbottomWidget, done_button); ac++;
    XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNtopWidget, assign_board); ac++;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNleftWidget, CatLabelDescr); ac++;
    CatLabel = XtCreateWidget(theDialog, xmTextWidgetClass, theDialog, al, ac);
    XmTextSetString(CatLabel, "cat label");
    XtAddCallback(CatLabel, XmNactivateCallback, CallInputOutput, INPUT);
    XtAddCallback(CatLabel, XmNlosingFocusCallback, CallInputOutput, INPUT);
    XmAddTabGroup(CatLabel);
    XtManageChild(CatLabel);

    return (theDialog);
}

Widget 
Create_Att_Table(parent, pal, pac)
    Widget          parent;
    Arg             *pal;
    int             pac;
{
    Widget          optionRC, acceptB, resetB;
    Display        *dpy = XtDisplay(shell);
    char            name[120];
    Arg             al[30];
    int             ac, i, scr = DefaultScreen(dpy);


    AttList = XtCreateWidget("AttList", xmFormWidgetClass, parent, pal, pac);
    XtManageChild(AttList);

    for (i = 0; i < NCOLS; i++) 
    {
	/* CREATE ATTR DESCRIPTION */
        sprintf(name, "lab%d", i + 1);
	if(i==5)
	   sprintf(name,"olechka-zain'ka");
        AttLabels[i] = XmCreateLabel(AttList, name, NULL, 0);
	XtManageChild(AttLabels[i]);

	/* CREATE ATTR TEXT EDIT FIELD */
        sprintf(name, "%3d", i + 1);
	AttTexts[i] = XtCreateWidget(name, xmTextWidgetClass, AttList, NULL, 0);
	XtManageChild(AttTexts[i]);

        /* CREATE LINK BUTTON IF EXISTS */
	if(link_exists(i))
	{
           sprintf(name, "link%d", i + 1);
           AttButtons[i] = XmCreatePushButton(AttList, name, NULL, 0);
	   XtManageChild(AttButtons[i]);
        }

        /* SET ARGUMENTS ATTRIBUTE DESCRIPTION */
        ac = 0;
	if(i==0)
	{
	   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
        }
        else
	{
	   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
           XtSetArg(al[ac], XmNtopWidget, AttTexts[i-1]); ac++;
        }
	XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
        sprintf(name, "lab%d", i + 1);
	if(i==5)
	   sprintf(name,"olechka-zain'ka ochen' horoshaya devochka  ");
        XtSetArg(al[ac], XmNlabelString,
             XmStringCreate(name, XmSTRING_DEFAULT_CHARSET));ac++;

	XtSetValues(AttLabels[i], al, ac);

	/* SET ARGUMENTS FOR TEXT EDIT FIELD */
        ac = 0;
	if(i==0)
	{
	   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
        }
        else
	{
	   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
           XtSetArg(al[ac], XmNtopWidget, AttTexts[i-1]); ac++;
        }
	if(!link_exists(i))
	{
	     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
	}
        else
	{
	     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
	     XtSetArg(al[ac], XmNrightWidget, AttButtons[i]); ac++;
        }
	XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
	XtSetArg(al[ac], XmNleftWidget, AttLabels[i]); ac++;
        values[i] = XtMalloc(20);
	/******** WIDTH */
        sprintf(values[i], "0");
	XmTextSetString(AttTexts[i], values[i]);
        XtAddCallback(AttTexts[i], XmNlosingFocusCallback, GetAttText, i);
	XtSetValues(AttTexts[i], al, ac);

        /* CREATE BUTTONS FOR FOREIGN KEYS */
	/* now if the attribute is a foreign or primary key, make a button */
	if(link_exists(i))
	/* make a button */
	{
	   ac = 0;
           sprintf(name, "link%d", i + 1);
	   if(i==0)
	   {
	     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
           }
           else
	   {
	     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
             XtSetArg(al[ac], XmNtopWidget, AttTexts[i-1]); ac++;
           }
           XtSetArg(al[ac], XmNlabelString,
             XmStringCreate("Follow Link", XmSTRING_DEFAULT_CHARSET)); ac++;
	   XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
	   XtSetValues(AttButtons[i], al, ac);
           XtAddCallback(AttButtons[i], XmNactivateCallback, follow_link, i);
	}

    }
    XtManageChildren(AttTexts, XtNumber(AttTexts));
    XtManageChildren(AttLabels, XtNumber(AttLabels));

    ac = 0;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
    XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
    XtSetArg(al[ac], XmNtopWidget, AttTexts[NCOLS-1]); ac++;
    XtSetArg(al[ac], XmNorientation, XmHORIZONTAL);
    ac++;
    optionRC = XmCreateForm(AttList, "optionRC", al, ac);
    XtManageChild(optionRC);

    ac = 0;
    XtSetArg(al[ac], XmNlabelString,
             XmStringCreate("Accept", XmSTRING_DEFAULT_CHARSET));
    ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM);
    ac++;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_POSITION);
    ac++;
    XtSetArg(al[ac], XmNrightPosition, 49);
    ac++;
    acceptB = XmCreatePushButton(optionRC, "acceptB", al, ac);
    XmAddTabGroup(acceptB);
    XtManageChild(acceptB);
    XtAddCallback(acceptB, XmNactivateCallback, CallAccept, AttList);

    ac = 0;
    XtSetArg(al[ac], XmNlabelString,
             XmStringCreate("Reset", XmSTRING_DEFAULT_CHARSET));
    ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET);
    ac++;
    XtSetArg(al[ac], XmNleftWidget, acceptB);
    ac++;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM);
    ac++;
    resetB = XmCreatePushButton(optionRC, "resetB", al, ac);
    XmAddTabGroup(resetB);
    XtManageChild(resetB);
    XtAddCallback(resetB, XmNactivateCallback, CallReset, AttList);

    return (AttList);
}

void 
follow_link(w, client_data, data)
    Widget          w;
    int             client_data;
    caddr_t         data;
{
    int i = client_data;
    printf("follow link: %d\n", i);
}

void 
GetAttText(w, client_data, call_data)
    Widget          w;
    int             client_data;
    caddr_t         call_data;
{
    int i = client_data;
    sprintf(values[i], "%s", XmTextGetString(w));
    printf("%d att: %s\n", i, values[i]);
}

void 
CallInputOutput(w, client_data, call_data)
    Widget          w;
    int             client_data;
    caddr_t         call_data;
{
    char            temp[256];

    sprintf(temp, "%s", XmTextGetString(w));
    printf("cat label: %s\n", temp);
}

void 
CallOk(w, parent, call_data)
    Widget          w, parent;
    caddr_t         call_data;
{
    int             i, err = 0;
    char            command[512];
    for (i = 0; i < NCOLS; i++) {
            sprintf(values[i], "%s", XmTextGetString(AttTexts[i]));
	    printf("col %d: %s\n", i, values[i]);
    }
    printf("att label: %s\n", XmTextGetString(CatLabel));
    XtUnmanageChild(parent);
}

void 
CallCancel(w, parent, call_data)
    Widget          w, parent;
    caddr_t         call_data;
{
    XFlush(display);
    XtUnmanageChild(parent);
}

void 
CallHelp(w, client_data, call_data)
    Widget          w;
    caddr_t         client_data, call_data;
{
    printf("Help is not yet available!\n");
}

void 
CallAccept(w, tb, call_data)
    Widget          w, tb;
    caddr_t         call_data;
{
    int             i, count = 0;
    char           *dists, *tok;
    char            temp[660], buf[11];

    for (i = 0; i < NCOLS; i++) {
            sprintf(values[i], "%s", XmTextGetString(AttTexts[i]));
	    printf("col %d: %s\n", i, values[i]);
    }
}

void 
CallReset(w, tb, call_data)
    Widget          w, tb;
    caddr_t         call_data;
{
    int             i;
    Time time;

    for (i = 0; i < NCOLS; i++) {
        sprintf(values[i], "");
	XmTextSetString(AttTexts[i], values[i]);
    }
}

static int link_exists(i)
   int i;
{
   return (i==2 || i==4 || i==5 || i==8);
}
