// TileScrollView.h
// By Jayson Adams, NeXT Developer Support Team
// You may freely copy, distribute and reuse the code in this example.
// NeXT disclaims any warranty of any kind, expressed or implied, as to its
// fitness for any particular use.


#import <appkit/ClipView.h>
#import <appkit/Scroller.h>
#import <appkit/Matrix.h>
#import <appkit/Text.h>
#import <appkit/NXImage.h>

#import <appkit/TextFieldCell.h>
#import <appkit/ButtonCell.h>
#import "StubView.h"
#import "SpreadSheetMgr.h"

#import "TileScrollView.h"

const char TileScrollView_h_rcsid[] = TILESCROOLVIEW_H;
const char TileScrollView_m_rcsid[] = "$Id";

#define printval(x) printf(""#x" = %f\n",(x))
#define RECELL_TIME		500

@implementation TileScrollView


/* instance methods */

- initFrame:(const NXRect *)theFrame
{
//	theFrame->origin.x = 0.0;
//	theFrame->origin.y = 0.0;

	[super initFrame:theFrame];

	//printf("TileScrollView: initFrame:\n");

	/* turn off drawing (to the screen) */
	[window disableFlushWindow];

	[self makelines:theFrame];
	[self makeColumns:theFrame];
	[self makeArrowMatrix];
	[self makeAddMatrix];

	/* send results to screen */
	[[window reenableFlushWindow] flushWindow];

	[self setAutoresizeSubviews:YES];
	return self;
}

- makelines:(const NXRect *)theFrame
 /* make a clipView to hold line number Matrix */
{
	NXRect              frameRect = {0.0, 0.0, 0.0, 0.0};
	NXRect				rulerViewRect;
	id                  cellPrototype;
	NXSize              size;

	cellPrototype = [[TextFieldCell alloc] initTextCell:"kkkkkk"];
	[cellPrototype setTextGray:NX_BLACK];
	[cellPrototype setBordered:YES];
	lineMatrix = [[Matrix alloc] initFrame:&frameRect mode:NX_TRACKMODE
		      prototype:cellPrototype numRows:0 numCols:0];
	size.width = 0.0;
	size.height = 0.0;
	[lineMatrix setIntercell:&size];
	stubView = [[StubView alloc] initFrame:&frameRect];

	[self addSubview:stubView];

	[lineMatrix setAutodisplay:NO];
	[lineMatrix setFrame:theFrame];
	[lineMatrix setCellBackgroundGray:NX_LTGRAY];
	[lineMatrix renewRows:DEFAULT_ROWS cols:1];
	[lineMatrix sizeToCells];
	{
		int                 i;

		for (i = 0; i < DEFAULT_ROWS; i++)
			[[lineMatrix cellAt:i :0] setIntValue:i];
	}
	[lineMatrix update];

	[lineMatrix getBounds:&rulerViewRect];
	lineMatrixClipView = [[ClipView alloc] initFrame:&rulerViewRect];
	[lineMatrixClipView setDocView:lineMatrix];
	[self addSubview:lineMatrixClipView];
	//[lineMatrixClipView sizeTo:rulerViewRect.size.width
	   //:rulerViewRect.size.width];

	return self;
}

- makeColumns:(const NXRect *)theFrame
 /* make a clipView to hold column Name Matrix */
{
	NXRect              frameRect = {45.0, 0.0, 0.0, 0.0};
	NXRect				rulerViewRect;
	NXSize              size = {80.0, 20.0};
	id                  cellPrototype;

	cellPrototype = [[TextFieldCell alloc] initTextCell:"           "];
	[cellPrototype setTextGray:NX_BLACK];
	[cellPrototype setBordered:YES];
	[cellPrototype setEditable:YES];
	[cellPrototype setAlignment:NX_CENTERED];

	colNameMatrix = [[Matrix alloc] initFrame:&frameRect mode:NX_TRACKMODE
			 prototype:cellPrototype numRows:0 numCols:0];
	[colNameMatrix setCellSize:&size];
	size.width = 0.0;
	size.height = 0.0;
	[colNameMatrix setIntercell:&size];

	[colNameMatrix setAutodisplay:NO];
	[colNameMatrix setFrame:theFrame];

	[colNameMatrix setCellBackgroundGray:NX_LTGRAY];
	[colNameMatrix renewRows:1 cols:DEFAULT_COLS];
	[colNameMatrix sizeToCells];
	//[colNameMatrix update];

	[colNameMatrix getBounds:&rulerViewRect];
	rulerViewRect.size.width -= 45.0;
	colNameMatrixClipView = [[ClipView alloc] initFrame:&rulerViewRect];
	[colNameMatrixClipView setDocView:colNameMatrix];
	[self addSubview:colNameMatrixClipView];
	/*
	 * [colNameMatrixClipView sizeTo:rulerViewRect.size.width
	 * :rulerViewRect.size.width]; 
	 */
	return self;
}

- makeArrowMatrix
{
	NXRect              frameRect = {148.0, 40.0, 20.0, 40.0};
	ButtonCell         *bCell;
	NXSize              aSize = {18.0, 18.0};

	bCell = [[ButtonCell alloc] initIconCell:"icon2"];
	[bCell setBordered:YES];
	arrowMatrix = [[Matrix alloc] initFrame:&frameRect mode:NX_TRACKMODE
		       prototype:bCell numRows:2 numCols:1];
	[[arrowMatrix cellAt:0 :0] setIcon:"icon3"];
	[[arrowMatrix cellAt:0 :0] setType:NX_MOMENTARYPUSH];
	[[arrowMatrix cellAt:1 :0] setType:NX_MOMENTARYPUSH];

	[arrowMatrix setCellSize:&aSize];
	[arrowMatrix update];

	return self;
}
- makeAddMatrix
{
	NXRect              frameRect = {148.0, 40.0, 20.0, 40.0};
	ButtonCell         *bCell;
	NXSize              aSize = {24.0, 18.0};

	bCell = [[ButtonCell alloc] initIconCell:"icon6"];
	[bCell setBordered:YES];
	addMatrix = [[Matrix alloc] initFrame:&frameRect mode:NX_TRACKMODE
		       prototype:bCell numRows:1 numCols:3];
	[[addMatrix cellAt:0 :0] setIcon:"icon5"];
	[[addMatrix cellAt:0 :0] setType:NX_MOMENTARYPUSH];
	[[addMatrix cellAt:0 :1] setType:NX_MOMENTARYPUSH];

	[addMatrix setCellSize:&aSize];
	[addMatrix update];

	return self;
}


- free
{
	return[super free];
}

- changeScale:sender
{

	return self;
}

- tile
/*
 * tile gets called whenever the scrollView changes size.  Its job is to resize
 * all of the scrollView's "tiled" views (scrollers, contentView and any other
 * views we might want to place in the scrollView's bounds).
 */
{
	NXRect              contentViewRect, rulerRect, rulerClipRect, scrollerRect, buttonRect, stubRect;

	//printf("tile\n");
	/* resize and arrange the scrollers and contentView as usual */
	[super tile];

	if ([arrowMatrix superview] != self) {
		[self addSubview:arrowMatrix];
	}
	if ([addMatrix superview] != self) {
		[self addSubview:addMatrix];
	}
	if ([colNameMatrixClipView superview] != self) {
		[self addSubview:colNameMatrixClipView];
	}
	if ([lineMatrixClipView superview] != self) {
		[self addSubview:lineMatrixClipView];
	}
	Controller = [self superview];
	[[[arrowMatrix cellAt:0 :0] setTarget:Controller]
	 setAction:@selector(readLess:)];
	[[[arrowMatrix cellAt:1 :0] setTarget:Controller]
	 setAction:@selector(readMore:)];
	[[[addMatrix cellAt:0 :0] setTarget:Controller]
	 setAction:@selector(addRowFunction:)];
	[[[addMatrix cellAt:0 :1] setTarget:Controller]
	 setAction:@selector(addColFunction:)];

	[Controller setColumnNameMatrix:colNameMatrix];
	[Controller setLineNumberMatrix:lineMatrix];
	/* MYCODE */


	[contentView getFrame:&contentViewRect];
	[colNameMatrix getFrame:&rulerRect];
	NXDivideRect(&contentViewRect, &rulerClipRect, NX_HEIGHT(&rulerRect), 1);
	rulerClipRect.origin.x += 45.0;
	rulerClipRect.size.width -= 45.0;
	[colNameMatrixClipView setFrame:&rulerClipRect];
	[contentView setFrame:&contentViewRect];
	[colNameMatrix update];

	/* shrink the vScroller to make room for the stub view */
	[stubView getFrame:&stubRect];
	[vScroller getFrame:&scrollerRect];
	NXDivideRect(&scrollerRect, &stubRect, NX_HEIGHT(&rulerClipRect), 1);
	[vScroller setFrame:&scrollerRect];
	stubRect.size.width += 45.0;
	[stubView setFrame:&stubRect];

	[stubView update];


	[contentView getFrame:&contentViewRect];
	[lineMatrix getFrame:&buttonRect];
	NXDivideRect(&contentViewRect, &rulerClipRect, NX_WIDTH(&buttonRect), 0);
	rulerClipRect.size.height -= 1;
	[lineMatrixClipView setFrame:&rulerClipRect];
	//[lineMatrixClipView translate:0 :298];
	[contentView setFrame:&contentViewRect];

	/*
	 * now make the vScroller smaller and stick the two buttons next to
	 * it 
	 */
	[arrowMatrix getFrame:&buttonRect];
	[vScroller getFrame:&scrollerRect];
	NXDivideRect(&scrollerRect, &buttonRect, 38.0, 3);
	[vScroller setFrame:&scrollerRect];
	//NXInsetRect(&buttonRect, 1.0, 1.0);
	[arrowMatrix setFrame:&buttonRect];

	/*
	 * now make the hScroller smaller and stick the two buttons next to
	 * it 
	 */
	[hScroller getFrame:&scrollerRect];
	[addMatrix getFrame:&buttonRect];
	NXDivideRect(&scrollerRect, &buttonRect, 66.0, 2);
	[hScroller setFrame:&scrollerRect];
	NXInsetRect(&buttonRect, 1.0, 1.0);
	[addMatrix setFrame:&buttonRect];

	return self;
}

- scrollClip:aClipView to:(NXPoint *)aPoint
{
	NXPoint             colOrigin;
	NXRect              colBounds;

	//printf("scroll\n");
	/* don't do anything if it's not the contentView */
	if (aClipView != contentView) {
		return self;
	}
	/* turn off drawing (to the screen) */
	[window disableFlushWindow];

	[aClipView rawScroll:aPoint];

	/* compute new origin for the colNameMatrix  */
	[colNameMatrixClipView getBounds:&colBounds];
	colOrigin.x = aPoint->x	/*- NX_SCROLLERWIDTH*//* + colBounds.origin.x *//* +
		     542.0 */ ;
	colOrigin.y = colBounds.origin.y;

	/* scroll the ruler view to that point */
	[colNameMatrixClipView rawScroll:&colOrigin];

	/*
	 * compute new origin for the line Matrix (don't let it scroll
	 * horizontally) 
	 */
	[lineMatrixClipView getBounds:&colBounds];
	colOrigin.x = colBounds.origin.x;
	//if (aPoint->y != colBounds.origin.y)
		colOrigin.y = aPoint->y	/*- 298.0*//*- colBounds.origin.y - 298.0*//* +
			    248.0 */ ;

	/* scroll the Matrix view to that point */
	[lineMatrixClipView rawScroll:&colOrigin];


	/* send results to screen */
	[[window reenableFlushWindow] flushWindow];

	return self;
}

- read:(NXTypedStream *) typedStream
{
	//printf("read:\n");
	[super read:typedStream];
	lineMatrix = NXReadObject(typedStream);
	lineMatrixClipView = NXReadObject(typedStream);
	colNameMatrix = NXReadObject(typedStream);
	colNameMatrixClipView = NXReadObject(typedStream);
	arrowMatrix = NXReadObject(typedStream);
	addMatrix = NXReadObject(typedStream);
	stubView = NXReadObject(typedStream);
	return self;
}

- write:(NXTypedStream *) typedStream
{
	//printf("write:\n");
	[super write:typedStream];
	NXWriteObject(typedStream, lineMatrix);
	NXWriteObject(typedStream, lineMatrixClipView);
	NXWriteObject(typedStream, colNameMatrix);
	NXWriteObject(typedStream, colNameMatrixClipView);
	NXWriteObject(typedStream, arrowMatrix);
	NXWriteObject(typedStream, addMatrix);
	NXWriteObject(typedStream, stubView);
	return self;
}

@end
