//
//  EXPPlotElement.m
//  XMLTest
//
//  Created by Ashley on 21/05/2007.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "EXPPlotElement.h"
#import "PLTMatrix.h"
#import "PLTMatrixColumnView.h"
#import "EXPModel.h"
#include <plplot/plConfig.h>
#include <plplot/plplot.h>

@implementation EXPPlotElement

+ (void) openWithDevice:(NSString *)device andFile:(NSString *)filename
{
	plsdev([device UTF8String]);
	if (filename!=nil) {
		plsfnam([filename UTF8String]);
	}
    plinit();
}

+ (void) close
{
    plend();
}
	
- (void) addItem:(id)item
{
	EXPExpressionList *list = [self expressionList];
	[list  addObject:item];
}

- (void) setModel:(id)model
{
	_model = model;
}

- (id) model
{
	return _model;
}

/*- (void) getPlotXmin:(double *)xmin xmax:(double *)xmax ymin:(double *)ymin ymax:(double *)ymax
{
	EXPModel *doc = [self model];
	
	NSArray *items = [[self expressionList] list];
	int nLines = [items count];
	if (nLines<2) {
		return;
	}
	
	int nPoints = [doc outputCounter];
	double *x = (double *)calloc(nPoints, sizeof(double));
	double *y = (double *)calloc(nPoints, sizeof(double));
	EXPElement *element = [items objectAtIndex:0];
	
	[self getValues:x element:element nValues:nPoints model:doc];
	int i;
	*xmin = x[0];
	*xmax = x[0]
	for(i=1; i<nPoints: i++) {
		if (x[i]>*xmax) {
			*xmax = x[i];
		}
		if(x[i]<*xmin) {
			*xmin = x[i];
		}
	}
	
	int j;
	for(j=1; j<nLines; j++) {
		element = [items objectAtIndex:j];
		[self getValues:y element:element nValues:nPoints model:doc];
		*ymin = y[0];
		*ymax = y[0]
		for(i=1; i<nPoints: i++) {
			if (y[i]>*ymax) {
				*ymax = y[i];
			}
			if(y[i]<*ymin) {
				*ymin = y[i];
			}
		}
	}
	
	free(x);
	free(y); 
}*/

/*- (void) getValues:(double *)values element:(EXPElement *)element nValues:(int)nPoints model:(EXPModel *)doc
{
//	tValues:(PLTMatrix *)tValues yValues:(PLTMatrix *)yValues auxValues:(PLTMatrix *)auxValues
	int address = 0;
	PLTMatrix *matrix = nil;
	
	PLTMatrix *tValues = [doc tValues];
	PLTMatrix *yValues = [doc yValues];
	PLTMatrix *auxValues = [doc auxValues];
	
	if ([element isMemberOfClass:[EXPFunctionElement class]]) {
		address = 0;
		matrix = tValues;
	} else if ([element isMemberOfClass:[EXPStateElement class]]) {
		address = [element address];
		matrix = yValues;
	} else if ([element isMemberOfClass:[EXPAuxiliaryElement class]]) {
		address = [element address];
		matrix = auxValues;
	}

//	double value;
	int i;
	for (i=0; i<nPoints; i++) {
		values[i] = [matrix cellAtRow:i andCol:address];
	} 
			
}*/

- (void) plot
{
	EXPModel *doc = [self model];
	
	PLTMatrix *outputValues = [doc outputValues];
	if (outputValues==nil) {
		return;
	}
	
	EXPStackMachine *machine = [doc machine];
	
	NSArray *items = [[self expressionList] list];

	EXPElement *tElement = [items objectAtIndex:0];
	int offset;
			
	if ([[tElement name] isEqualToString:@"t"]) {
		offset = 0;
	} else if ([tElement isMemberOfClass:[EXPStateElement class]]) {
		offset = [tElement address] + 1;
	} else if ([tElement isMemberOfClass:[EXPAuxiliaryElement class]]) {
		offset = [tElement address] + [machine nVariables] + 1;
	}
	
	NSNumber *number = [[NSNumber alloc] initWithInt:offset];
	NSArray *tColumn = [[NSArray alloc] initWithObjects:number, nil];
	[number release];
	
	PLTMatrixColumnView *tView = [[PLTMatrixColumnView alloc] initColumnViewWithMatrix:outputValues withColumns:tColumn];

	[tColumn release];

	NSMutableArray *columns = [[NSMutableArray alloc] init];
	
	int j;
	for (j=1; j<[items count]; j++) {
		EXPElement *element = [items objectAtIndex:j];
		int offset;
			
		if ([[element name] isEqualToString:@"t"]) {
			offset = 0;
		} else if ([element isMemberOfClass:[EXPStateElement class]]) {
			offset = [element address] + 1;
		} else if ([element isMemberOfClass:[EXPAuxiliaryElement class]]) {
			offset = [element address] + [machine nVariables] + 1;
		}
		
		NSNumber *number = [[NSNumber alloc] initWithInt:offset];
		[columns addObject:number];
		[number release];
			
	}
	
	PLTMatrixColumnView *view = [[PLTMatrixColumnView alloc] initColumnViewWithMatrix:outputValues withColumns:columns];
	[columns release];
	
	int nPoints = [doc outputCounter];
	double *x = (double *)calloc(nPoints, sizeof(double));
	int i;
	for(i=0; i<nPoints; i++) {
		x[i] = [tView cellAtRow:i andCol:0];
	}
	
	double *y = (double *)calloc(nPoints, sizeof(double));

	double xmin, xmax;
	[tView minAndMaxValues:&xmin and:&xmax];
	
	double ymin, ymax;
	[view minAndMaxValues:&ymin and:&ymax];
	
    plenv(xmin, xmax, ymin, ymax, 0, 1);
	
	for(j=0; j<[view cols]; j++) {
		for(i=0; i<nPoints; i++) {
			y[i] = [view cellAtRow:i andCol:j];
		}
		
		plline(nPoints, x, y);
	}

	free(x);
	free(y);
	[view release];
	[tView release];
	
/*	NSArray *items = [[self expressionList] list];
	int nLines = [items count];
	if (nLines<2) {
		return;
	}
	
	int nPoints = [doc outputCounter];
	double *x = (double *)calloc(nPoints, sizeof(double));
	double *y = (double *)calloc(nPoints, sizeof(double));
	EXPElement *element = [items objectAtIndex:0];
	
	[self getValues:x element:element nValues:nPoints model:doc];
	
	int j;
	for(j=1; j<nLines; j++) {
		element = [items objectAtIndex:j];
		[self getValues:y element:element nValues:nPoints model:doc];
		plline(nPoints, x, y);
	}
	
	free(x);
	free(y); */
}

@end
