/* 
   PXKView.m

   NSView for GNUstep GUI X/DPS Backend.

   Copyright (C) 1996 Free Software Foundation, Inc.

   Author:  Pascal Forget <pascal@wsc.com>
   Date: January 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/PXKView.h>

static NSView *focusView;

// Back-end instance variables structures
typedef struct _PXKView_struct
{
  int viewNum;
} PXKView_struct;

#define VIEW_NUM (((PXKView_struct *)be_view_reserved)->viewNum)

@implementation PXKView

- (void)displayIfNeeded
{
    if ((super_view != nil) && (needs_display == YES)) {
	
	if (VIEW_NUM < 0) {
	  //	    VIEW_NUM = createView(self, [super_view viewNum]);

	    if (VIEW_NUM <0) {
		fprintf(stderr, "NSView display: error creating the view's "
			"windowing system-specific implementation.\n"); 
		/* Should raise exception here */
	    }
	}

	//	displayView(VIEW_NUM);

	if (opaque == YES) {
	    [sub_views makeObjectsPerform:@selector(display)];
	}
    }
}

- (void)displayIfNeededIgnoringOpacity
{
    if ((super_view != nil) && (needs_display == YES)) {
	
	if (VIEW_NUM < 0) {
	  //	    VIEW_NUM = createView(self, [super_view viewNum]);

	    if (VIEW_NUM <0) {
		fprintf(stderr, "NSView display: error creating the view's "
			"windowing system-specific implementation.\n"); 
		/* Should raise exception here */
	    }
	}

	//	displayView(VIEW_NUM);
	[sub_views makeObjectsPerform:@selector(display)];
    }
}

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

    // Allocate back-end structure
    be_view_reserved = malloc(sizeof(PXKView_struct));

    VIEW_NUM = -1;

    return self;
}

- (void)dealloc
{
  // Release back-end structure
  free(be_view_reserved);

  [super dealloc];
}

- (void)lockFocus
{
  [super lockFocus];
}

- (NSView *)opaqueAncestor
{
    if (super_view != nil) {
	if ([super_view isOpaque]) {
	    return super_view;
	} else {
	    return [super_view opaqueAncestor];
	}
    }

    return nil;
}   

/*
 * removeFromSuperview removes the receiver from the view hierarchy.
 * My (Pascal) interpretation of the previous line is that the view
 * will not only be removed from the view hierarchy, but it will
 * effectively disappear from the screen.
 */

- (void)removeFromSuperview
{
    if (super_view != nil) {
	[(NSMutableArray *)[super_view subviews] removeObject:self];
    }

    /*
     * Destroy the X Window that provided
     *  the on-screen representation for this view
     */
    if (VIEW_NUM > -1) {       
      //	destroyView(VIEW_NUM);
	VIEW_NUM = -1;
	window = nil;
    }
}

- (void)replaceSubview:(NSView *)oldView with:(NSView *)newView
{
    unsigned int index = [sub_views indexOfObject:oldView];

    if (index != NSNotFound) {
	if (newView != nil) {
	    [sub_views replaceObjectAtIndex:index withObject:newView];
	    [newView setSuperview:self];
	} else {
	    [sub_views removeObject:oldView];
	}
	[oldView setSuperview:nil];
    }
}
	
- (void)rotateByAngle:(float)angle
{
    frame_rotation += angle;
    setViewFrameRotation(VIEW_NUM, frame_rotation);
}

- (void)setFrame:(NSRect)frameRect
{
  [super setFrame: frameRect];

    //    setViewFrame(VIEW_NUM, frame);
    //    [self resizeSubviewsOldSize:oldSize newSize:frame.size];
}

- (void)setFrameOrigin:(NSPoint)newOrigin
{
#if 1
    frame.origin.x = newOrigin.x;
    frame.origin.y = newOrigin.y;

    setViewFrameOrigin(VIEW_NUM, newOrigin);

    if ((post_frame_changes == YES) && (super_view != nil))
    {
	/* Notify superview.  (OpenStep does not specify selector -Duh.) */
    }
#endif    
}

- (void)setFrameRotation:(float)angle
{
    if (frame_rotation != angle) {
	frame_rotation = angle;
	setViewFrameRotation(VIEW_NUM, frame_rotation);
	
	if ((post_frame_changes == YES) && (super_view != nil)) {
	    /* Notify superview.  (OpenStep does not specify selector -Duh.) */
	}
    }
}

- (void)setFrameSize:(NSSize)newSize
{
    NSSize oldSize = frame.size;
#if 1    
    frame.size = newSize;
    
    setViewFrameSize(VIEW_NUM, newSize);

    if ((post_frame_changes == YES) && (super_view != nil)) {
	/* Notify superview.  (OpenStep does not specify selector -Duh.) */
    }

    [self resizeSubviewsOldSize:oldSize newSize:newSize];
#endif    
}

- (void)unlockFocus
{
    if (focusView == self) {
	focusView = nil;
    }
}

- (id)viewWithTag:(int)aTag
{
    unsigned int i, count = [sub_views count];
    NSView *aSubview;
    
    for (i=0; i<count; i++) {

	aSubview = [sub_views objectAtIndex:i];

	if ([aSubview tag] == aTag) {
	    return aSubview;
	}
    }
    return nil; /* Not found */
}

- (void)setSuperview:(NSView *)aView
{
    super_view = aView;
    
    if (aView != nil) {
	window = [super_view window];
    } else {
	window = nil;
	/*
	 * Destroy the X Window that provided
	 *  the on-screen representation for this view
	 */
	if (VIEW_NUM > -1) {       
	  //	    destroyView(VIEW_NUM);
	    VIEW_NUM = -1;
	}
    }
}

@end

@implementation NSView (NonOpenStep)

- (void)resizeSubviewsOldSize:(NSSize)oldSize newSize:(NSSize)newSize
{
    if ((autoresize_subviews == YES) &&
	((oldSize.width != newSize.width) ||
	 (oldSize.height != newSize.height)))
    {
	[self resizeSubviewsOldSize:oldSize];
    }
}

- (void)resizeSubviewsOldSize:(NSSize)oldSize
{
    NSView *aSubview;
    int index = [sub_views count];
	
    while (index > 0) {
	aSubview = [sub_views objectAtIndex:index];
	[aSubview superviewSizeChanged:oldSize];
	index--;
    }
}

- (int)viewNum
{
    return VIEW_NUM;
}

@end
