/* 
   PXKScrollView.m

   Copyright (C) 1996 Free Software Foundation, Inc.

   Author:  Pascal Forget <pascal@wsc.com>
   Date: October 1995
   
   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/PXKScrollView.h>
#include <gnustep/xdps/PXKTestImage.h>
#include <gnustep/xdps/PXKButton.h>
#include <gnustep/xdps/PXKMatrix.h>
#include <gnustep/xdps/PXKView.h>

@implementation PXKScrollView

- (PXKClipView *)clipView;
{
    return [sub_views objectAtIndex:0];
}

- (void)display;
{
    [self placeSubviews];
    XFlush(pxkDisplay);
    XMapWindow(pxkDisplay, [(PXKView *)self xWindow]);
    XClearWindow(pxkDisplay, [(PXKView *)self xWindow]);
    XMapSubwindows(pxkDisplay, [(PXKView *)self xWindow]);

    [(PXKClipView *)[sub_views objectAtIndex:0] display];

    if (yScrollerVisible) {
	[(PXKScroller *)[sub_views objectAtIndex:1] display];
    } else {
	[(PXKScroller *)[sub_views objectAtIndex:1] close];
    }
	
    if (xScrollerVisible) {
	[(PXKScroller *)[sub_views objectAtIndex:2] display];
    } else {
	[(PXKScroller *)[sub_views objectAtIndex:2] close];
    }

    [self drawBorder];
    
    XFlush(pxkDisplay);    
    return self;
}

- drawBorder;
{
  //    (void)load_font(&win_font);

    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkDarkgrayGC,
	      0,0,frame.size.width-1,0);
    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkDarkgrayGC,
	      0,1,0,frame.size.height-1);

    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC,
	      1,1,frame.size.width-2,1);
    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkBlackGC,
	      1,2,1,frame.size.height-2);

    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkWhiteGC, 
	      0, frame.size.height-1,
	      frame.size.width-1, frame.size.height-1);

    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkWhiteGC,
	      frame.size.width-1, 0,
	      frame.size.width-1, frame.size.height-1);

    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkLightgrayGC, 
	      1, frame.size.height-2,
	      frame.size.width-2, frame.size.height-2);

    XDrawLine(pxkDisplay, [(PXKView *)self xWindow], pxkLightgrayGC,
	      frame.size.width-2, 1,
	      frame.size.width-2, frame.size.height-2);
    
    
#if 0    
    XDrawLine(pxkDisplay, xWindow, pxkWhiteGC, 0, frame.size.height-1,
	      frame.size.width-1, frame.size.height-1);
    XDrawLine(pxkDisplay, xWindow, pxkWhiteGC, frame.size.width-1,
	      0, frame.size.width-1, frame.size.height-1);
    
    XDrawLine(pxkDisplay, xWindow, pxkWhiteGC, 2, frame.size.height-2,
	      frame.size.width-2, frame.size.height-2);
    XDrawLine(pxkDisplay, xWindow, pxkWhiteGC, frame.size.width-2,
	      1, frame.size.width-2, frame.size.height-2);
    
    /* using drawing color white */
    XDrawLine(pxkDisplay, xWindow, pxkBlackGC,0,0,frame.size.width-2,0);
    XDrawLine(pxkDisplay, xWindow, pxkBlackGC,0,0,0,frame.size.height-2);
#endif
    return self;
}

- initWithSuperview:(PXKView *)aView;
{
#if 0
    PXKTestImage *c;
    PXKButton *b;
    NSSize s;
    NSRect r;
#endif
    
    PXKClipView *clipView;
    
    [super initWithSuperview:aView];

    yScrollerLeft = NO;
    yScrollerVisible = YES;
    xScrollerVisible = YES;

    clipView = [[PXKClipView alloc] initWithSuperview:self];
    
    [sub_views addObject:clipView];
    [sub_views addObject:[[PXKScroller alloc] initWithSuperview:self]];
    [sub_views addObject:[[PXKScroller alloc] initWithSuperview:self]];

#if 0

    s.width = 900;
    s.height= 500;
    
    c = [[PXKTestImage alloc] initWithSize:s];
    [c setName:"Stupid screen grab"];
    b = [[PXKButton alloc] initWithSuperview:clipView];

    r.origin.x = 0;
    r.origin.y = 0;
    r.size.width = 900;
    r.size.height= 500;
    [b setFrame:r];
    [b setImage:c];
    [b setTitle:[[PXKString alloc] initWithCString:""]];
    [clipView setView:b];
#endif
        
    return self;
}

- (void)hideXScroller;
{
    xScrollerVisible = NO;
}

- (void)hideYScroller;
{
    yScrollerVisible = NO;
}

#define PXK_SCROLLER_SIDE 20

- placeSubviews;
{
    NSRect cRect;
    NSRect yRect = [(PXKScroller *)[sub_views objectAtIndex:1] frame];
    NSRect xRect = [(PXKScroller *)[sub_views objectAtIndex:2] frame];

    yRect.size.width = PXK_SCROLLER_SIDE;
    xRect.size.height= PXK_SCROLLER_SIDE;
    cRect.origin.y = 2;
    
#if 0
    fprintf(stdout, "before clipView: %d %d %d %d\n", cRect.origin.x,
	    cRect.origin.y, cRect.size.width, cRect.size.height);

    fprintf(stdout, "before vert scroller: %d %d %d %d\n", yRect.origin.x,
	    yRect.origin.y, yRect.size.width, yRect.size.height);

    fprintf(stdout, "before horiz scroller: %d %d %d %d\n", xRect.origin.x,
	    xRect.origin.y, xRect.size.width, xRect.size.height);
    
    puts("ScrollView: placing subviews");

#endif    
    
    if (yScrollerLeft) {

	if (yScrollerVisible) {

	    /* Place vertical scroller */

	    yRect.origin.x = 1;
	    yRect.origin.y = 1;
	    yRect.size.height = frame.size.height-2;

	    /* Place clipView */

	    cRect.origin.x = yRect.size.width + 2;
	    cRect.size.width = frame.size.width - cRect.origin.x - 1;
	    cRect.origin.y = 2;
	
	    if (xScrollerVisible) {
		cRect.size.height = frame.size.height - xRect.size.height - 4;
	    } else {
		[(PXKView *)[sub_views objectAtIndex:2] close];
		xRect.size.height = 0;
		cRect.size.height = frame.size.height - 4;
	    }

	} else {

	    /* Place vertical scroller */
	    yRect.size.height = 0;
	    
	    /* Place clipView */

	    cRect.origin.x =  2;
	    cRect.size.width = frame.size.width - 4;
	    cRect.origin.y = 2;
	
	    if (xScrollerVisible) {
		cRect.size.height = frame.size.height - xRect.size.height - 4;
	    } else {
		[(PXKView *)[sub_views objectAtIndex:2] close];
		xRect.size.height = 0;
		cRect.size.height = frame.size.height - 4;
	    }

	    [(PXKView *)[sub_views objectAtIndex:1] close];
	}
    } else { /* The vertical scroller is at the right of the clip view */
	if (yScrollerVisible) {

	    /* Place vertical scroller */

	    yRect.origin.x = frame.size.width - PXK_SCROLLER_SIDE-2;
	    yRect.origin.y = 1;
	    yRect.size.height = frame.size.height-2;
	    
	    /* Place clipView */

	    cRect.origin.x = 2;
	    cRect.size.width = frame.size.width - yRect.size.width - 4;
	    cRect.origin.y = 2;
	
	    if (xScrollerVisible) {
		cRect.size.height = frame.size.height - xRect.size.height - 4;
	    } else {
		[(PXKView *)[sub_views objectAtIndex:2] close];
		xRect.size.height = 0;
		cRect.size.height = frame.size.height - 4;
	    }

	} else {

	    /* Place vertical scroller */
	    yRect.size.height = 0;
	    
	    /* Place clipView */

	    cRect.origin.x =  2;
	    cRect.size.width = frame.size.width - 4;
	    cRect.origin.y = 2;
	
	    if (xScrollerVisible) {
		cRect.size.height = frame.size.height - xRect.size.height - 4;
	    } else {
		xRect.size.height = 0;
		[(PXKView *)[sub_views objectAtIndex:2] close];
		cRect.size.height = frame.size.height - 4;
	    }

	    [(PXKView *)[sub_views objectAtIndex:1] close];
	}
    }

    /* Place horizontal scroller */

    if (xScrollerVisible) {
	if (yScrollerLeft) {
	    xRect.origin.x = cRect.origin.x - 1;
	} else {
	    xRect.origin.x = 1;
	}
	xRect.size.width = cRect.size.width + 1;
	xRect.origin.y = frame.size.height - xRect.size.height - 1;
    }

#if 0
    fprintf(stdout, "clipView: %d %d %d %d\n", cRect.origin.x,
	    cRect.origin.y, cRect.size.width, cRect.size.height);

    fprintf(stdout, "vert scroller: %d %d %d %d\n", yRect.origin.x,
	    yRect.origin.y, yRect.size.width, yRect.size.height);

    fprintf(stdout, "horiz scroller: %d %d %d %d\n", xRect.origin.x,
	    xRect.origin.y, xRect.size.width, xRect.size.height);
#endif

    [(PXKView *)[sub_views objectAtIndex:0] setFrame:cRect];
    [(PXKView *)[sub_views objectAtIndex:1] setFrame:yRect];
    [(PXKView *)[sub_views objectAtIndex:2] setFrame:xRect];
	
    return self;
}

- (void)putYScrollerToTheLeft;
{
    yScrollerLeft = YES;
}
    
- (void)putYScrollerToTheRight;
{
    yScrollerLeft = NO;
}

- (void)showXScroller;
{
    xScrollerVisible = YES;
}

- (void)showYScroller;
{
    yScrollerVisible = YES;
}

- (PXKScroller *)xScroller;
{
    return [sub_views objectAtIndex:2];
}

- (PXKScroller *)yScroller;
{
    return [sub_views objectAtIndex:1];
}

- xScrolled;
{
    float relativePos = [[sub_views objectAtIndex:2] relativePosition];

    [(PXKClipView *)[sub_views objectAtIndex:0] 
		    setXRelativePosition:relativePos];

    [[sub_views objectAtIndex:0] display];
    
    return self;
}

- yScrolled;
{
    float relativePos = [[sub_views objectAtIndex:1] relativePosition];
    
    [(PXKClipView *)[sub_views objectAtIndex:0] 
		    setYRelativePosition:relativePos];

    [[sub_views objectAtIndex:0] display];
    return self;
}

- updateScrollers; /* Message sent from ClipView object */
{
    PXKClipView *clipView = [sub_views objectAtIndex:0];
    PXKMatrix *docView = [clipView view];
    NSRect clipR = [clipView frame];
    NSRect viewR = [docView frame];
    float xRatio = clipR.size.width / (float)viewR.size.width;
    float yRatio = clipR.size.height / (float)viewR.size.height;
    float min;
    float max;
    float pos;

    puts("update scrollers");

#if 0
    fprintf(stdout, "clipView: %d %d %d %d\n", clipR.origin.x,
	    clipR.origin.y, clipR.size.width, clipR.size.height);
    
    fprintf(stdout, "docView: %d %d %d %d\n", viewR.origin.x,
	    viewR.origin.y, viewR.size.width, viewR.size.height);
#endif
    
    /*
     * set the ratios for the scroll buttons.
     */
    
    if (xRatio > 1.0) {
	xRatio = 1.0;
    }
    
    if (yRatio > 1.0) {
	yRatio = 1.0;
    }

    [(PXKScroller *)[sub_views objectAtIndex:1] setRatio:yRatio];    
    [(PXKScroller *)[sub_views objectAtIndex:2] setRatio:xRatio];

    /*
     * determine the current value for each scroller
     */
    min = [(PXKScroller *)[sub_views objectAtIndex:1] minValue];
    max = [(PXKScroller *)[sub_views objectAtIndex:1] maxValue];
    
    pos = (-1) * viewR.origin.y + clipR.size.height/2.0;

    [(PXKScroller *)[sub_views objectAtIndex:1] setCurrentValue:
		     (max-min) * (pos / (float)viewR.size.height)];
    
    min = [(PXKScroller *)[sub_views objectAtIndex:2] minValue];
    max = [(PXKScroller *)[sub_views objectAtIndex:2] maxValue];
    
    pos = (-1) * viewR.origin.x + clipR.size.width/2.0;

    [(PXKScroller *)[sub_views objectAtIndex:1] setCurrentValue:
		     (max-min) * (pos / (float)viewR.size.width)];
    
    return self;
}

@end
