

#import "iCursorAppDelegate.h"
#import "particlesystems.h"

cScene* scene = NULL;
int counter   = 0;

int currEffect      = 0;
bool firstBoot      = true;
bool paused         = false;
float scaleFactor   = 1.0;

extern char pSystemName[MAX_EFFECT][255];

@implementation iCursorAppDelegate

//---------------------------------------------------------------------------------------

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

- (void)ReadPrefs
{
	if ([prefs boolForKey:@"first_time"] == false)
	{

		firstBoot  = (bool)[prefs boolForKey:@"first_time"];
        paused     = (bool)[prefs boolForKey:@"paused_fx"];
		currEffect = (int)[prefs  integerForKey:@"current_fx"];
        
        scene->renderActive = !paused;
	}
}
//---------------------------------------------------------------------------------------

- (void)WritePrefs
{
	[prefs setBool:firstBoot forKey:@"first_time"];
    [prefs setBool:paused forKey:@"paused_fx"];
	[prefs setInteger:currEffect forKey:@"current_fx"];
	[prefs synchronize];
}

//---------------------------------------------------------------------------------------

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{
	// Insert code here to initialize your application 
	[self InitWindow]; 
    [self InitOpenGL]; 
	[self ReadPrefs];
    [self FillMenu];
    
    PrepParticleSystem(currEffect);
    scene->renderActive = !paused;
	
    [Startup display];
    [Startup makeKeyAndOrderFront:NSApp];
    [Startup setLevel:NSMainMenuWindowLevel /* + 1*/];
        
    NSApplication *thisApp = [NSApplication sharedApplication];
    [thisApp activateIgnoringOtherApps:YES];
    
    firstBoot = false;
    [self WritePrefs];
}

//---------------------------------------------------------------------------------------

-(void)awakeFromNib
{
	statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
	[statusItem setMenu:statusMenu];
	[statusMenu setAutoenablesItems:YES];
	NSImage * tray_image = [NSImage imageNamed:@"trayicon.png"];
	[statusItem setImage:tray_image];
	[statusItem setHighlightMode:YES];
}

//---------------------------------------------------------------------------------------

- (void)FillMenu
{
    NSMenuItem *item_pause = [statusMenu addItemWithTitle:@"Pause" action:@selector(MenuWasChanged:) keyEquivalent:@""];
    [item_pause setState:paused];
    NSImage * item_image_pause = [NSImage imageNamed:@"menu_pause.png"];
    [item_pause setImage:item_image_pause];
    
    NSMenuItem *item_quit = [statusMenu addItemWithTitle:@"Quit"  action:@selector(terminate:) keyEquivalent:@""];
    [item_quit setState:0];
    NSImage * item_image_quit = [NSImage imageNamed:@"menu_quit.png"];
    [item_quit setImage:item_image_quit];
    
    [statusMenu addItem:[NSMenuItem separatorItem]];
    
	//filla i menu con i sistemi disponibili
	for (int i=0;i<MAX_EFFECT;i++)
	{
		NSString* itemName = [NSString stringWithUTF8String: pSystemName[i]];	
		NSMenuItem *item = [statusMenu addItemWithTitle:itemName action:@selector(MenuWasChanged:) keyEquivalent:@""];
		
		char pIconName[255];
		sprintf(pIconName,"menu_%d.png",i);
		NSString* itemImage = [NSString stringWithUTF8String: pIconName];
		NSImage * item_image = [NSImage imageNamed:itemImage];
		[item setImage:item_image];
		if (currEffect == i)
			[item setState:1];
			
		[item setTarget:self];

	}
}

//---------------------------------------------------------------------------------------

- (void)MenuWasChanged:(id)sender 
{
    
    //identifica l'indice del menu
	int idx = (int)[statusMenu indexOfItemWithTitle:(NSString *)[sender title]];
	
	if (idx >= 0+3 && idx < MAX_EFFECT+3)
	{
        //se scelto un altro effetto, ed e' in pausa, esclude la pausa
        paused = false;
        [[statusMenu itemAtIndex:0] setState:0];
        
        //elimina tutte le check degli effetti
        for (int i = 0+3;i<MAX_EFFECT+3; i++)
            [[statusMenu itemAtIndex:i] setState:0];
        
        //...e rimette quella corrente
        [[statusMenu itemAtIndex:idx] setState:1];
        
		scene->Stop();
		currEffect = idx-3;
		PrepParticleSystem(currEffect);
		scene->Start();
	}
    //altrimenti setta/esclude la pausa
    else if (idx == 0)
    {
        paused = !paused;
        [[statusMenu itemAtIndex:0] setState:paused];
        
        if (paused) 
        {   
            glClear(GL_COLOR_BUFFER_BIT);
            [glContext flushBuffer];
        }
        scene->renderActive = !paused;
    }
    
    //salva qualsiasi cambiamento
    [self WritePrefs];
}

//---------------------------------------------------------------------------------------

- (void)InitWindow
{

    NSRect tempRect=[[NSScreen mainScreen] frame]; //0,0,1920,1080
	dWindow  = [[NSWindow alloc] initWithContentRect:
                                        tempRect
                                        styleMask:NSBorderlessWindowMask
                                        backing:NSBackingStoreBuffered
                                        defer:NO];
										
	[dWindow setBackgroundColor:[NSColor clearColor]];
	[dWindow makeKeyAndOrderFront:NSApp];				//fronte a tutte
	[dWindow setOpaque:NO];
	[dWindow setLevel:NSMainMenuWindowLevel + 1];		//copre la barra menu
	[dWindow setIgnoresMouseEvents:YES];

    [dWindow setCollectionBehavior:
     (NSWindowCollectionBehaviorCanJoinAllSpaces | 
      NSWindowCollectionBehaviorStationary | 
      NSWindowCollectionBehaviorIgnoresCycle)];

    NSScreen* tScreen = [NSScreen mainScreen];
    scaleFactor =  tScreen.backingScaleFactor;
    if (scaleFactor < 1.0)
        scaleFactor = 1.0;
    
    //TODO
    //printf("iCursor scaleFactor %.2f\n",scaleFactor);
}

//---------------------------------------------------------------------------------------

- (void) InitOpenGL
{

	NSOpenGLPixelFormatAttribute attributes [] = 
	{
        NSOpenGLPFANoRecovery,
		NSOpenGLPFAAccelerated,
		NSOpenGLPFAColorSize,32,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFADepthSize,16,
        0,
    };
	
    NSRect tempRect=[dWindow frame]; //0,0,1920,1080
    float delta = 1;
    tempRect.origin.x    += delta;
    tempRect.origin.y    += delta;
    tempRect.size.width  -= (delta * 3);
    tempRect.size.height -= (delta * 3);
    
    NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
    glView = [[NSOpenGLView alloc] initWithFrame:tempRect pixelFormat:format];
	[[dWindow contentView] addSubview:glView];
	glContext = [glView openGLContext];

	GLint swapInterval = 1;
	GLint opacity      = 0;
	[glContext setValues: &swapInterval  forParameter: NSOpenGLCPSwapInterval];
	[glContext setValues: &opacity       forParameter: NSOpenGLCPSurfaceOpacity];
	[glContext makeCurrentContext];
	NSRect tFrame = [dWindow frame];
    
	//prep engine
	NSBundle *currBundle = [NSBundle bundleForClass: [self class]];
	NSString *s = [currBundle bundlePath];
	char* result = (char*)[s UTF8String];
	scene = new cScene(result);
    
    //TEST
    //RETINA
    float dpi = [[NSScreen mainScreen] backingScaleFactor];
    scene->resolutionX = (float)((float)([[NSScreen mainScreen] frame].size.width) * (float)dpi);
    scene->resolutionY = (float)((float)([[NSScreen mainScreen] frame].size.height) * (float)dpi);

    //OLD
    //scene->resolutionX = tFrame.size.width;
	//scene->resolutionY = tFrame.size.height;
	
    scene->SetColor(0,0,0,0);
    
    //TODO
    //printf("iCursor resolution is %dx%d\n",scene->resolutionX,scene->resolutionY);
    
	//cagate...
	glShadeModel( GL_SMOOTH );
	glClearColor(0,0,0,0);
    glClearDepth( 1.0f );
	glDisable( GL_DEPTH_TEST );
	glDepthMask(FALSE);
	glEnable(GL_TEXTURE_2D);
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	glDisable(GL_ALPHA_TEST);
  
	//frustum
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, tFrame.size.width, 0, tFrame.size.height,-8000, +8000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glViewport(0,0,tFrame.size.width,tFrame.size.height);
	
	//begin mess
	PreloadTextures();
    scene->renderActive = false;
	scene->SetColor(0,0,0,0);
    
	timer = [NSTimer timerWithTimeInterval:(1.0f/30.0f) target:self selector:@selector(RenderTimer) userInfo:nil repeats:YES];
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
}
//---------------------------------------------------------------------------------------

- (void)RenderTimer
{
    if (!scene->renderActive)
        return;
    
	[glContext makeCurrentContext];

	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
	
	if (scene && scene->pParticle[0])
	{
		mouseLoc = [NSEvent mouseLocation];
        
        //TODO
        //printf("iCursor mouseLocation %dx%d\n",(int)mouseLoc.x,(int)mouseLoc.y);
        
		scene->pParticle[0]->SetPosition(
            (mouseLoc.x + x_offset),// * scaleFactor,
            (mouseLoc.y - y_offset),// * scaleFactor,
            +1);
        
		scene->pParticle[0]->Render();
        
        if (++counter > 2)
        {
            IdleParticleEffect(currEffect);
            counter = 0;
        }
	}
	
	[glContext flushBuffer];

}

//---------------------------------------------------------------------------------------

@end
