/* 
   PXKTextField.m

   NSTextField for GNUstep GUI X/DPS Backend.

   Copyright (C) 1996 Free Software Foundation, Inc.

   Author:  Pascal Forget <pascal@wsc.com>
   Date: March 1996
   
   This file is part of the GNUstep GUI X/DPS Backend.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
   
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   If you are interested in a warranty or support for this source code,
   contact Scott Christley <scottc@net-community.com> for more information.
   
   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ 

#include <gnustep/xdps/PXKTextField.h>
#include <gnustep/xdps/PXKView.h>
#include <gnustep/xdps/PXKApplication.h>

XFontStruct *win_font;

@implementation PXKTextField

- initWithFrame:(NSRect)frameRect;
{
    [super initWithFrame:frameRect];

    //    isBeingEdited = NO;
    
    return self;
}

- (void)display;
{
    [super display];

    XClearWindow(pxkDisplay, [(PXKView *)self xWindow]);
    
    if ([self isEnabled] == NO) {
	XDefineCursor(pxkDisplay,[(PXKView *)self xWindow],
		      XCreateFontCursor(pxkDisplay, XC_xterm));
    }

    [self drawRect:bounds];
    [self drawBorder];
}

- (void)drawRect:(NSRect)rect;
{
    int len1;
    int width;
    int font_height;
    NSString *value;
    NSTextAlignment alignment = [self alignment];

    /* need length for both XTextWidth and XDrawString */
    value = [self stringValue];
    len1 = [value length];

    if (!win_font) {
	fprintf(stderr, "Error loading font. Exiting.\n");
	exit(-1);
    }
    
    /* get string widths for centering */
    width = XTextWidth(win_font, [value cString], len1);

    font_height = win_font->ascent + win_font->descent;

    /*
     * Wipe out the contents of the window by filling its
     * area with the backGroundColor (defined in PXKView.h)
     */
    XFillRectangle(pxkDisplay, [(PXKView *)self xWindow], pxkWhiteGC,
		   frame.origin.x+2, frame.origin.y+2,
		   frame.size.width-4, frame.size.height-4);

    [self drawBorder];

    if((alignment == NSLeftTextAlignment) && (width < frame.size.width)) {
	XDrawString(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC, 
		    5, font_height,
		    [value cString], len1);
    } else if((alignment == NSRightTextAlignment) 
	      && ((width+5)<frame.size.width)) {
      XDrawString(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC,
		  frame.size.width - 5 - width, font_height,
		  [value cString], len1);
    } else {

	if (width > (frame.size.width-4)) {
	    XDrawString(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC,
			(frame.size.width - width-5), 
			font_height, [value cString], len1);	    
	} else {
	    /* output text, centered on each line */
	    XDrawString(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC,
			(frame.size.width - width-6)/2, 
			font_height, [value cString], len1);
	}
    }
}

- drawBorder;
{
    if (!win_font) {
	load_font(&win_font);
    }
    
    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC, 
	      0, 0, frame.size.width,0);
    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC, 
	      0, 0, 0, frame.size.height);

    XFlush(pxkDisplay);

    /* Draw the bottom and right borders */
    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkLightgrayGC, 
	      2, frame.size.height-2,
	      frame.size.width,frame.size.height-2);
    
    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkLightgrayGC, 
	      frame.size.width-2, 2,
	      frame.size.width-2, frame.size.height-2);

    return self;
}

/*
 * Get characters until you encounter
 * a carriage return, return number of characters.
 * Deal with backspaces, etc.  Deal with Expose events
 * on all windows associated with this application.
 * Deal with keyboard remapping.
 */

#if 0
- keyDown:(XEvent *)e;
{
    XEvent report;
    KeySym keysym;
    XComposeStatus compose;    
    int count, length;
    char buffer[MAX_MAPPED_STRING_LENGTH];
    int bufsize=MAX_MAPPED_STRING_LENGTH;

    report = *e;    
    fprintf(stdout, "PXKTextField keyDown:\n");
    
    count = XLookupString(&report, buffer, bufsize, &keysym, &compose);

    /*
     * now need to do the right thing with
     * every keysym possibility, as minimum:
     */
    if ((keysym == XK_Return) ||
	(keysym == XK_KP_Enter) ||
	(keysym == XK_Linefeed))
    {
      //isBeingEdited = NO;
    } else if (((keysym >= XK_KP_Space) && (keysym <= XK_KP_9))
	       ||
	       ((keysym >= XK_space) && (keysym <= XK_asciitilde)))
    {
	if ((strlen(stringValue) + count) >= 2048)
	{
	    XBell(pxkDisplay, 0);
	} else {
	    if (stringValue!= NULL) {
		stringValue = realloc(stringValue,
				      strlen(stringValue) + count + 1);
	    } else {
		stringValue = malloc(count + 1);
	    }
	    (void)strncat(stringValue, buffer, count);
	}
    }
    else if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R))
	;/* do nothing because its a modifier key */
    else if ((keysym >= XK_F1) && (keysym <= XK_F35))
	if (buffer == NULL)
	    printf("Unmapped function key\n");
	else if ((strlen(stringValue) + count)>= MAX_POPUP_STRING_LENGTH)
	{
	    XBell(pxkDisplay, 0);
	} else {
	    if (stringValue!= NULL) {
		stringValue = realloc(stringValue,
				      strlen(stringValue) + count + 1);
	    } else {
		stringValue = malloc(count + 1);
	    }	    
	    (void)strncat(stringValue, buffer, count);
	}
    
    else if ((keysym == XK_BackSpace) || (keysym == XK_Delete)) {
	if ((length = strlen(stringValue)) > 0) {
	    stringValue[length - 1] = NULL;
	    XClearWindow(pxkDisplay, xWindow);
	} else {
	    XBell(pxkDisplay, 0);
	}
    }
    else {
	printf("keysym %s is not handled\n",
	       XKeysymToString(keysym));
	XBell(pxkDisplay, 0);
    }
    [self display];
    /* clear buffer so multi-character strings
     * are properly supported, even though
     * they can only be deleted one char at a
     * time */
    buffer[1] = NULL;

    return self;
}

- mouseDown:(XEvent *)e;
{   
    fprintf(stdout, "PXKTextField mouseDown:\n");
    
    //    if (!isBeingEdited) {

    XSelectInput(pxkDisplay, xWindow, (ExposureMask | KeyPressMask));
    [self display];

    //isBeingEdited = YES;
    //    } else {
    /* Nothing to do (until selection is implemented) */
    //}

    return self;
}
#endif

@end
