/*
 * Copyright(c) 1992 Bell Communications Research, Inc. (Bellcore)
 *                        All rights reserved
 * Permission to use, copy, modify and distribute this material for
 * any purpose and without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies, and that the name of Bellcore not be used in advertising
 * or publicity pertaining to this material without the specific,
 * prior written permission of an authorized representative of
 * Bellcore.
 *
 * BELLCORE MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES, EX-
 * PRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST IN-
 * FRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS.  THE
 * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL BELLCORE OR
 * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
 * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELAT-
 * ING TO THE SOFTWARE.
 *
 * $Id: select-drag.c,v 1.1 1999/08/04 21:24:20 danny Exp $
 */


#ifdef HAVE_CONFIG_H
#include <XbaeConfig.h>
#endif

#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/PushB.h>
#include <Xbae/Matrix.h>
#include <Xm/PanedW.h>

void LoadMatrix();
void SelectCB();
void ResetCB();

/*
 * Create an uneditable matrix. When Btn1 is dragged, a rectangular region
 * of cells is selected.
 */

int
main(argc, argv)
int argc;
char *argv[];
{
    Widget toplevel, matrix, pb, pane;
    XtAppContext app;
#ifdef USE_EDITRES
    extern void _XEditResCheckMessages();
#endif

    toplevel = XtAppInitialize(
	&app, "Select-drag", NULL, 0, &argc, argv, NULL, NULL, 0);
#ifdef USE_EDITRES
    XtAddEventHandler(toplevel, (EventMask)0, True,
                       _XEditResCheckMessages, NULL);
#endif

    pane = XtVaCreateManagedWidget(
	"pane", xmPanedWindowWidgetClass, toplevel,
	NULL);

    pb = XtVaCreateManagedWidget(
	"Reset", xmPushButtonWidgetClass, pane,
	NULL);

    matrix = XtVaCreateManagedWidget(
	"matrix", xbaeMatrixWidgetClass, pane,
	XmNtopAttachment, XmATTACH_FORM,
	XmNbottomAttachment, XmATTACH_FORM,
	XmNleftAttachment, XmATTACH_FORM,
	XmNtopAttachment, XmATTACH_FORM,
	NULL);

    XtAddCallback(matrix, XmNselectCellCallback, SelectCB, NULL);

    XtAddCallback(pb, XmNactivateCallback, ResetCB, (XtPointer)matrix);
    
    LoadMatrix(matrix);

    XtRealizeWidget(toplevel);
    XtAppMainLoop(app);
    return 0;
}

/*
 * Callback when the mouse is moved, we want to select a rectangle of cells
 */
/* ARGSUSED */
void
SelectCB(w, client_data, call_data)
Widget w;
XtPointer client_data;
XbaeMatrixSelectCellCallbackStruct *call_data;
{
    static int start_row = -1, start_column = -1;
    static int last_row = -1, last_column = -1;
    int i, j;

    /*
     * Avoid scrolling all over the place when selecting cells
     */
    /*XtVaSetValues(w, XmNselectScrollVisible, False, NULL);*/

    if (call_data->num_params == 0)
    {
	start_row = last_row = call_data->row;
	start_column = last_column = call_data->column;
	XbaeMatrixSelectCell(w, last_row, last_column);
    }
    /*
     * Else we might be in an extended drag operation
     */
    else if (!strcmp(call_data->params[ 0 ], "extend"))
    {
	/*
	 * This is a pretty simplistic, stupid implementation
	 * of selecting a rectangle.
	 */
	if (call_data->row > last_row) {
	    for (i = last_row + 1; i <= call_data->row; i++)
		for (j = start_column; j <= call_data->column; j++)
		    XbaeMatrixSelectCell(w, i, j);
	}
	if (call_data->column > last_column) {
	    for (i = start_row; i <= last_row; i++)
		for (j = last_column + 1; j <= call_data->column; j++)
		    XbaeMatrixSelectCell(w, i, j);
	}
	last_row = call_data->row;
	last_column = call_data->column;
printf("%d, %d\n", last_row, last_column);
    }
    /*XtVaSetValues(w, XmNselectScrollVisible, True, NULL);*/
}

/* ARGSUSED */
void
LoadMatrix(matrix)
Widget matrix;
{
    int i, j;
    int rows, columns;
    char buf[BUFSIZ];
    String **cells;

    XtVaGetValues(matrix,
		  XmNrows, &rows,
		  XmNcolumns, &columns,
		  NULL);

    cells = (String **) XtMalloc(sizeof(String *) * rows);
    for (i = 0; i < rows; i++) {
	cells[i] = (String *) XtMalloc(sizeof(String) * columns);
	for (j = 0; j < columns; j++) {
	    sprintf(buf, "r%dc%d", i, j);
	    cells[i][j] = XtNewString(buf);
	}
    }

    XtVaSetValues(matrix,
		  XmNcells, cells,
		  NULL);

    for (i = 0; i < rows; i++) {
	for (j = 0; j < columns; j++)
	    XtFree((XtPointer)cells[i][j]);
	XtFree((XtPointer)cells[i]);
    }
    XtFree((XtPointer)cells);
}

void
ResetCB(w, cd, cb)
Widget w;
XtPointer cd;
XtPointer cb;
{
    Widget mw = (Widget)cd;

    XbaeMatrixDeselectAll(mw);
}
