/* Implementation of MList class
 *
 * Copyright (C)  1993, 1994, 1995  The Board of Trustees of  
 * The Leland Stanford Junior University.  All Rights Reserved.
 *
 * Authors: Scott Francis, Fred Harris, Paul Kunz, Tom Pavel, 
 *	    Imran Qureshi, and Libing Wang
 *
 * This file is part of an Objective-C class library for X/Motif
 *
 * MList.m,v 1.42 1995/04/17 22:44:49 fedor Exp
 */

/* Implementation Note:  This non-OpenStep class is used as
 * temporary replacement for a matrix of SelectionCells.  It will
 * be eliminated later
 */
 
#include "MList.h"
#include "xtResponder.h"

/* Required for implementation: */
#include "Motif.h"
#include <Xm/List.h>
#include <Xm/TextF.h>
#include <objc/List.h>
#include "ActionCell.h"
#include "Application.h"
#include "Matrix.h"
#include "ClipView.h"
#include <stdlib.h>             /* for free()   */

#define CELL_HEIGHT 17

static void
click(Widget w, XtPointer client_data, XtPointer call_data)
{
    MList *listid = (MList *)client_data;
    XmListCallbackStruct *cb = (XmListCallbackStruct *) call_data;

    switch (cb->reason) {
      case XmCR_BROWSE_SELECT:
         [[listid target] perform:[listid action] with:listid]; 
         break;
      case XmCR_DEFAULT_ACTION:
         [[listid target] perform:[listid doubleAction] with:listid];
         break; 
      default:
         break;
    }
}

@interface View(WidgetSet)
- _init;
@end

@implementation MList 

- initFrame:(const NXRect *)frameRect
{
    [super initFrame:frameRect];
    instancename = "MList";
    return self;
}

- _init
{
    [super _init];
    classname = xmListWidgetClass;
    return self;
}

- fillListFrom:(Matrix *)aMatrix
{
    Cell		*aCell;
    List		*list;
    XmStringTable	items;
    char	*fontName = "-adobe-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*";
    XFontStruct	*font;
    XmFontList	fontList;
    Display	*disp = [NXApp _X_display];
    Pixel	black;
    NXRect	superframe;
    char	*string;
    int		i, count;

    [self empty];
    if ( widgetid ) {
	XtUnmanageChild(widgetid);
	XtDestroyWidget(widgetid);
    }
    widgetid = NULL;
    list = [aMatrix cellList];
    count = [list count];
    if (count == 0) 
	items = NULL;
    else
    	items = (XmStringTable)malloc( count*sizeof(XmString *) );

    for ( i = 0; i < count; i++ ) {
	aCell = [list objectAt:i];
	string = (char *)[aCell stringValue];
	items[i] = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET);
    }
    frame.origin.x = frame.origin.y = 0;
    frame.size.height = count * CELL_HEIGHT + 0.4 * CELL_HEIGHT;
    [superview getFrame:&superframe];
    if ( superframe.size.height > frame.size.height ) {
	frame.origin.y = superframe.size.height - frame.size.height;
    }
    font = XLoadQueryFont( disp, fontName );
    fontList = XmFontListCreate( font, XmSTRING_DEFAULT_CHARSET );
    black = XBlackPixel(disp, XDefaultScreen(disp));
    [self _addArg:XmNwidth  :frame.size.width];
    [self _addArg:XmNheight :frame.size.height];
    [self _addArg:XmNitemCount :count];
    [self _addArg:XmNitems :(XtArgVal)items];
    [self _addArg:XmNvisibleItemCount :count];
    [self _addArg:XmNfontList :(XtArgVal)fontList];
    [self _addArg:XmNforeground :black];
    if ( [superview _widget] ) {
	[self _managedBy:superview];
	[(ClipView *)superview _setScrollFloatValue:0.0 :0.0];
	i = count;
	while ( i-- ) {
	    XmStringFree( items[i] );
	}
	free( items );
    }
    return self;
}

- empty
{
    if ( widgetid ) {
	XmListDeleteAllItems(widgetid);
    }
    return self;
}

- getSelectedCells:(List *)aList from:(Matrix *)cellMatrix
{
    Cell	*aCell;
    List	*selList;
    int 	*position_list, position_count;
    int		i, pos;
    Boolean	flag;
    
    if ( aList ) {
        selList = aList;
    } else {
        selList = [[List alloc] init];
    }
    flag = XmListGetSelectedPos(widgetid, &position_list, &position_count); 
    if ( flag == FALSE ) 
        return selList;
    for ( i = 0; i < position_count; i++ ) {
        pos = position_list[i] -1;
	aCell = [cellMatrix cellAt:pos :0];
	[selList addObject:aCell];
    }
    return selList;
}


- selectCellAt:(int)row
{
    XmListSelectPos ( widgetid, row+1, False );
    return self;
}

- setTarget:anObject
{
    target = anObject;
    return self;
}

- target
{
    return target;
}

- setAction:(SEL)aSelector
{
    action = aSelector;
    return self;
}

- (SEL)action
{
    return action;
}

- setDoubleAction:(SEL)aSelector
{
    doubleAction = aSelector;
    return self;
}

- (SEL)doubleAction
{
    return doubleAction;
}

-free
{
    [self empty];
    return [super free];
}

- _addCallback
{
    XtAddCallback(widgetid, XmNbrowseSelectionCallback, 
                     click, (XtPointer)self);
    XtAddCallback(widgetid, XmNdefaultActionCallback,
                     click, (XtPointer)self);
    return self;
}

- _managedBy:parent wid:(void*)widget
{
    int temp = 500;
    
    [self _addArg:XmNdoubleClickInterval:temp];
    [self _addArg:XmNshadowThickness :0];
    [super _managedBy:parent wid:widget];
    return self;
}
@end
