#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>

#import "SchemeTypes.h"
#import "Primitive.h"

#define GSCHEME @"GScheme by Marko Riedel, mriedel@neuearbeit.de\n"

typedef enum {
    MODE_INTERACTIVE = 0,
    MODE_EVALUATE,
    MODE_LOAD
} PROCESS_MODE;

typedef enum {
    DRAW_MOVE = 0,
    DRAW_LINE,
    DRAW_COLOR,
    DRAW_CIRCLE,
    FILL_CIRCLE,
    DRAW_RECT,
    FILL_RECT,
    DRAW_FONT,
    DRAW_STRING
} DRAW_INST;

typedef struct _DrawInst {
    DRAW_INST what;
    union {
        NSPoint coord;
        float color[3];
	float radius;
	NSFont *font;
	NSString *string;
	NSSize size;
    } data;
} DrawInst;

@interface VScheme : NSObject
{
    int errpos;
    BOOL errflag;
    NSString *errmsg;

    NSMutableArray *codeStack;
    NSMutableArray *pcStack;
    NSMutableArray *argStack;
    NSMutableArray *envStack;

    id *curcodes;
    int curpc;
    int curlength;

    BOOL hadOutput;
    NSMutableString *output;

    int maxcode, maxpc, maxarg, maxenv;

    id delegate;

    BOOL atImgStart;
    NSPoint imgMin, imgMax;
    NSPoint imgCur;
    NSMutableArray *imgCodes;
    NSFont *imgFont;

    BOOL interrupted;
}

+ (NSString *)valToString:(id)item seen:(NSMutableSet *)mem;
+ (NSString *)valToString:(id)item;

+ printInstr:(Triple *)instr;
+ printCodes:(ByteCodes *)codes;

- init;

- delegate;
- setDelegate:(id)aDelegate;

- makeStartEnvironment;

- (int)maxcode;
- (int)maxpc;
- (int)maxarg;
- (int)maxenv;

- resetStacks;
- reset:(id)sender;

- appendToOutput:(NSString *)data;
- (NSString *)output;
- clearOutput;

- (NSSize)stringAtCurrentFont:(NSString *)str;
- recordImgInst:(DrawInst)inst;
- clearImage;
- produceImage;

- (NSMutableArray *)argStack;
- (NSMutableArray *)envStack;
- (NSMutableArray *)codeStack;

- (BOOL)errflag;
- (int)errpos;
- (NSString *)errmsg;

- args2list:(int)lower;

- pushByteCodes:(ByteCodes *)bcodes;

- interrupt:(id)sender;
- (BOOL)run:(ByteCodes *)prog mode:(PROCESS_MODE)pmode;

- special:(id)data output:(ByteCodes *)codes popenv:(int)ec;
- sequence:(id)data output:(ByteCodes *)codes popenv:(int)ec;
- compile:(id)data output:(ByteCodes *)codes popenv:(int)ec;

- (BOOL)compile:(id)data output:(ByteCodes *)codes;

- parse:(NSString *)scmText;
- (BOOL)processString:(NSString *)data mode:(PROCESS_MODE)pmode;

@end

@interface SCMImageView : NSView
{
    NSImage *image;
}

- (id)initWithFrame:(NSRect)frameRect;

- (NSImage *)image;
- setImage:(NSImage *)anImage;

- (void)drawRect:(NSRect)aRect;

@end


