#import <Cocoa/Cocoa.h>
#include <OpenGL/OpenGL.h>

@interface YsMacDelegate : NSObject /* < NSApplicationDelegate > */
/* Example: Fire has the same problem no explanation */
{
}
/* - (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication; */
@end

@implementation YsMacDelegate
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
	return YES;
}
@end



static void YsPollEvent(void)
{
 	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

	while(1)
	{
	 	[pool release];
	 	pool=[[NSAutoreleasePool alloc] init];
	
		NSEvent *event;
		event=[NSApp
			   nextEventMatchingMask:NSAnyEventMask
			   untilDate: [NSDate distantPast]
			   inMode: NSDefaultRunLoopMode
			   dequeue:YES];
		if(event!=nil)
		{
			[NSApp sendEvent:event];
			[NSApp updateWindows];
		}
		else
		{
			break;
		}
	}

	[pool release];	
}

@interface YsOpenGLWindow : NSWindow
{
}

@end

@implementation YsOpenGLWindow
- (void) keyDown:(NSEvent *)theEvent
{
	NSString *chrs;
	chrs=[theEvent characters];
	if([chrs length]>0)
	{
		int unicode;
		unicode=[chrs characterAtIndex:0];
		printf("keyDown %d\n",unicode);
	}
}

- (void) keyUp:(NSEvent *)theEvent
{
	NSString *chrs;
	chrs=[theEvent characters];
	if([chrs length]>0)
	{
		int unicode;
		unicode=[chrs characterAtIndex:0];
		printf("keyUp %d\n",unicode);
	}
}

- (void) mouseDown:(NSEvent *)theEvent
{
	printf("%s %d %d\n",__FUNCTION__,(int)[theEvent locationInWindow].x,(int)[theEvent locationInWindow].y);
}

- (void) mouseUp:(NSEvent *)theEvent
{
	printf("%s %d %d\n",__FUNCTION__,(int)[theEvent locationInWindow].x,(int)[theEvent locationInWindow].y);
}

- (void) rightMouseDown:(NSEvent *)theEvent
{
	printf("%s %d %d\n",__FUNCTION__,(int)[theEvent locationInWindow].x,(int)[theEvent locationInWindow].y);
}

- (void) rightMouseUp:(NSEvent *)theEvent
{
	printf("%s %d %d\n",__FUNCTION__,(int)[theEvent locationInWindow].x,(int)[theEvent locationInWindow].y);
}

- (void) otherMouseDown:(NSEvent *)theEvent
{
	printf("%s %d %d\n",__FUNCTION__,(int)[theEvent locationInWindow].x,(int)[theEvent locationInWindow].y);
}

- (void) otherMouseUp:(NSEvent *)theEvent
{
	printf("%s %d %d\n",__FUNCTION__,(int)[theEvent locationInWindow].x,(int)[theEvent locationInWindow].y);
}

- (void) mouseMoved:(NSEvent *)theEvent
{
	printf("%s %d %d\n",__FUNCTION__,(int)[theEvent locationInWindow].x,(int)[theEvent locationInWindow].y);
}

- (id) initWithContentRect: (NSRect)rect styleMask:(NSUInteger)wndStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferFlg
{
	[super initWithContentRect:rect styleMask:wndStyle backing:bufferingType defer:deferFlg];

	[[NSNotificationCenter defaultCenter] 
		addObserver:self
		selector:@selector(windowDidResize:)
		name:NSWindowDidResizeNotification
		object:self];

	[[NSNotificationCenter defaultCenter]
	  addObserver:self
	  selector:@selector(windowWillClose:)
	  name:NSWindowWillCloseNotification
	  object:self];

	[self setAcceptsMouseMovedEvents:YES];

	printf("%s\n",__FUNCTION__);
	return self;
}

- (void) windowDidResize: (NSNotification *)notification
{
	printf("%s\n",__FUNCTION__);
}

- (void) windowWillClose: (NSNotification *)notification
{
	printf("%s\n",__FUNCTION__);
	[NSApp terminate:nil];	// This can also be exit(0);
}

@end


@interface YsOpenGLView : NSOpenGLView 
{
}
- (void) drawRect: (NSRect) bounds;
@end

@implementation YsOpenGLView
-(void) drawRect: (NSRect) bounds
{
}
@end




static YsOpenGLWindow *ysWnd=nil;
static YsOpenGLView *ysView=nil;

static void YsSwapBuffers(void)
{
  [[ysView openGLContext] flushBuffer];
}

static void YsOpenWindow(void)
{
 	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];


	[NSApplication sharedApplication];
	[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];

	YsMacDelegate *delegate;
	delegate=[YsMacDelegate alloc];
	[delegate init];
	[NSApp setDelegate: delegate];
	
	[NSApp finishLaunching];



	NSRect contRect;
	contRect=NSMakeRect(32, 32, 800, 600);  // Top-Y coordinate is neglected.  Why?
	
	unsigned int winStyle=
	  NSTitledWindowMask|
	  NSClosableWindowMask|
	  NSMiniaturizableWindowMask|
	  NSResizableWindowMask;
	
	ysWnd=[YsOpenGLWindow alloc];
	[ysWnd
		initWithContentRect:contRect
		styleMask:winStyle
		backing:NSBackingStoreBuffered 
		defer:NO];

	NSOpenGLPixelFormat *format;
	NSOpenGLPixelFormatAttribute formatAttrib[]=
	{
		NSOpenGLPFAWindow,
		NSOpenGLPFADepthSize,(NSOpenGLPixelFormatAttribute)32,
		NSOpenGLPFADoubleBuffer,
		0
	};
	format=[NSOpenGLPixelFormat alloc];
	[format initWithAttributes: formatAttrib];
	
	ysView=[YsOpenGLView alloc];
	contRect=NSMakeRect(0,0,800,600);
	[ysView
		initWithFrame:contRect
		pixelFormat:format];
	
	[ysWnd setContentView:ysView];
	[ysWnd makeFirstResponder:ysView];

	[ysWnd makeKeyAndOrderFront:nil];
	[ysWnd makeMainWindow];

	[NSApp activateIgnoringOtherApps:YES];

	[pool release];
}

#define PI 3.1415927

void DrawTriangle(double angle)
{
	glClearColor(0,0,0,0);
	glClear(GL_COLOR_BUFFER_BIT);
	
	glColor3ub(0,255,0);
	
	glBegin(GL_POLYGON);
	glVertex2f(cos(angle),sin(angle));
	glVertex2f(cos(angle+PI*2.0/3.0),sin(angle+PI*2.0/3.0));
	glVertex2f(cos(angle+PI*4.0/3.0),sin(angle+PI*4.0/3.0));
	glEnd();

	glFlush();

	YsSwapBuffers();
};

void YsAddMenu(void)
{
 	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

	NSMenu *mainMenu;

	mainMenu=[NSMenu alloc];
	[mainMenu initWithTitle:@"Minimum"];

	NSMenuItem *fileMenu;
	fileMenu=[[NSMenuItem alloc] initWithTitle:@"File" action:NULL keyEquivalent:[NSString string]];
	[mainMenu addItem:fileMenu];

	NSMenu *fileSubMenu;
	fileSubMenu=[[NSMenu alloc] initWithTitle:@"FileMenu"];
	[fileMenu setSubmenu:fileSubMenu];

	NSMenuItem *fileMenu_Quit;
	fileMenu_Quit=[[NSMenuItem alloc] initWithTitle:@"Quit"  action:@selector(terminate:) keyEquivalent:@"q"];
	[fileMenu_Quit setTarget:NSApp];
	[fileSubMenu addItem:fileMenu_Quit];

	[NSApp setMainMenu:mainMenu];

	[pool release];
}

void YsTestApplicationPath(void)
{
 	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

	char cwd[256];
	getcwd(cwd,255);
	printf("CWD(Initial): %s\n",cwd);

	NSString *path;
	path=[[NSBundle mainBundle] bundlePath];
	printf("BundlePath:%s\n",[path UTF8String]);

	[[NSFileManager defaultManager] changeCurrentDirectoryPath:path];

	getcwd(cwd,255);
	printf("CWD(Changed): %s\n",cwd);

	[pool release];
}

void YsSleep(int ms)
{
  double sec;
  sec=(double)ms/1000.0;
  [NSThread sleepForTimeInterval:0.02];
}

int main(int argc, char *argv[])
{
	YsTestApplicationPath();

	YsOpenWindow();
	YsAddMenu();

	double angle;
	angle=0.0;
	while(1)
	{
		YsPollEvent();

		DrawTriangle(angle);
		angle=angle+0.05;

		YsSleep(20);
	}

	return 0;
}
