//
//  EAGLView.m
//  Week3WithText2D
//
//  Created by Ay on 2008/9/22.
//  Copyright NA 2008. All rights reserved.
//


/*
 _______________
 |             |
 |             |
 |             |
 |             |
 |             |
 |	_	_	_  |
 | |_| |_| |_| |
 |_____________|
 */

#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>

#import "EAGLView.h"

#define USE_DEPTH_BUFFER 0
#define SPRITE_WIDTH 128
#define SPRITE_HEIGHT 128
#define FIRST_LEVEL -2.0
#define SECOND_LEVEL -3.0
#define SHOW_CHANGE 0
#define SHOW_RANGE 5
#define SCORES_PER_EACH 20
#define SCORES_DEDUCE 5
#define TOP_MARGIN 165

// A class extension to declare private methods
@interface EAGLView ()

@property (nonatomic, retain) EAGLContext *context;
@property (nonatomic, assign) NSTimer *animationTimer;

- (BOOL) createFramebuffer;
- (void) destroyFramebuffer;

@end


@implementation EAGLView

@synthesize context;
@synthesize animationTimer;
@synthesize animationInterval;
@synthesize scores;


const GLfloat spriteLocation[] ={
0,200,90,200,180,200,
0, 110,90,110,180,110,
0, 10, 90,10, 180,10
};

GLfloat spriteEventCount[] ={
0,0,0,0,0,0,0,0,0
};

GLfloat spriteEventDir[] ={
1,-1,1,-1,1,-1,1,-1,1
};

// You must implement this
+ (Class)layerClass {
	return [CAEAGLLayer class];
}


//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {

	if ((self = [super initWithCoder:coder])) {
		// Get the layer
		CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
		
		eaglLayer.opaque = YES;
		eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
		   [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
		
		context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
		
		if (!context || ![EAGLContext setCurrentContext:context]) {
			[self release];
			return nil;
		}
		
		/**********Added By Ay************/
		bg= [[Texture2D alloc] initWithImagePath:@"lime-green-bubbles-iphone-wallpaper.jpg"];
		spriteFront = [[Texture2D alloc] initWithImagePath:@"font.png"];
		spriteBack = [[Texture2D alloc] initWithImagePath:@"back.png"];
		/*********************************/
		
		animationInterval = 1.0 / 60.0;
	}
	return self;
}


- (void)drawView {
		
	/**********Added By Ay************/	
	
	[EAGLContext setCurrentContext:context];
	
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
	
	[bg drawAtPoint:CGPointMake(backingWidth/2,backingHeight/2)];

	if(gameCount++ == 120){
		gameCount=0;
	}
	if(gameCount==0){
		//NSLog(@"Render");
		for(int i=0;i<3;i++){
			for(int j=0;j<3;j++){
				if(showStatus[0][i][j]==2)
					continue;
				if(rand()%SHOW_RANGE ==SHOW_CHANGE){
					showStatus[0][i][j] = 1;
				}else{ 
					showStatus[0][i][j] = 0;
				}
			}
		}
	}
	/** layer control **/
	
	//normal display
	for(int i=0;i<9;i++){
		if(showStatus[0][i/3][i%3]==1){
			[spriteFront drawInRect:CGRectMake(spriteLocation[i*2], spriteLocation[i*2+1], SPRITE_WIDTH, SPRITE_HEIGHT)];
		}
	}
	
	//enlarge display
	for(int i=0;i<9;i++){
		if(showStatus[0][i/3][i%3]==2 && spriteEventDir[i] == 1){
			spriteEventCount[i] += 0.05;
			if(spriteEventCount[i]>1){
				showStatus[0][i/3][i%3]=0;
				spriteEventCount[i]=0;
				if(rand()%2){
					spriteEventDir[i] = 1;
				}else{
					spriteEventDir[i] = -1;
				}
				continue;
			}			
			[spriteFront drawInRect:CGRectMake(spriteLocation[i*2]+(spriteEventDir[i]*spriteEventCount[i]*50), spriteLocation[i*2+1]+spriteEventDir[i]*spriteEventCount[i]*50, SPRITE_WIDTH-spriteEventDir[i]*spriteEventCount[i]*100, SPRITE_HEIGHT-spriteEventDir[i]*spriteEventCount[i]*100)];
		} 
	}
	
	//small display
	for(int i=0;i<9;i++){
		if(showStatus[0][i/3][i%3]==2 && spriteEventDir[i] == -1){
			spriteEventCount[i] += 0.05;
			if(spriteEventCount[i]>1){
				showStatus[0][i/3][i%3]=0;
				spriteEventCount[i]=0;
				if(rand()%2){
					spriteEventDir[i] = 1;
				}else{
					spriteEventDir[i] = -1;
				}
				continue;
			}			
			[spriteFront drawInRect:CGRectMake(spriteLocation[i*2]+(spriteEventDir[i]*spriteEventCount[i]*50), spriteLocation[i*2+1]+spriteEventDir[i]*spriteEventCount[i]*50, SPRITE_WIDTH-spriteEventDir[i]*spriteEventCount[i]*100, SPRITE_HEIGHT-spriteEventDir[i]*spriteEventCount[i]*100)];
		} 
	}
	/*********************************/
	
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
	[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {	
	NSLog( @"Touches Began");
}



- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	NSLog(@"Touches Moved");
	CGPoint point = [[touches anyObject] locationInView:self];
	
	NSLog([NSString stringWithFormat:@"%0.2f", point.x]);
	NSLog([NSString stringWithFormat:@"%0.2f", point.y]);
	if(point.y<TOP_MARGIN)
		return;
	for(int i =0;i<1;i++){

		int y = lrint(point.x - 60)/80;
		int x= lrint(point.y - 165)/100;
		NSLog([NSString stringWithFormat:@"showStatus %d",showStatus[0][x][y]]);
		
		if(showStatus[0][x][y] == 1){
			showStatus[0][x][y] = 2;
			scores += SCORES_PER_EACH;
			//label.text = [NSString stringWithFormat:@"scores end touch: %d",scores];
			NSLog([NSString stringWithFormat:@"scores end touch: %d",scores]);
		}
	}
	
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	NSLog(@"No Touch Event");
	
	for (UITouch *touch in touches) {
		CGPoint point = [touch locationInView:self];
		
		NSLog([NSString stringWithFormat:@"%0.2f", point.x]);
		NSLog([NSString stringWithFormat:@"%0.2f", point.y]);
		if(point.y<TOP_MARGIN)
			continue;
		for(int i =0;i<1;i++){
			
			int y = lrint(point.x - 60)/80;
			int x= lrint(point.y - 165)/100;
			NSLog([NSString stringWithFormat:@"showStatus %d in x:%d ,y:%d",showStatus[0][x][y],x,y]);
			
			if(showStatus[0][x][y] == 1){
				showStatus[0][x][y] = 2;
				scores += SCORES_PER_EACH;
				//label.text = [NSString stringWithFormat:@"scores end touch: %d",scores];
				NSLog([NSString stringWithFormat:@"scores end touch: %d",scores]);
			}
		}
		
		if (touch.tapCount == 2) {
			NSLog(@"Double Tapped");
		}else if(touch.tapCount>2){
			NSLog([NSString stringWithFormat:@"Tap Count : %d",touch.tapCount]);
		}
	}
}



- (void)layoutSubviews {
	[EAGLContext setCurrentContext:context];
	[self destroyFramebuffer];
	[self createFramebuffer];
	
	/**********Added By Ay************/	
	glViewport(0, 0, backingWidth, backingHeight);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrthof(0, (float)backingWidth, 0, (float)backingHeight, 0, 100);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	
	glEnableClientState (GL_VERTEX_ARRAY);
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
	
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	/*********************************/
	
	[self drawView];
}


- (BOOL)createFramebuffer {
	
	glGenFramebuffersOES(1, &viewFramebuffer);
	glGenRenderbuffersOES(1, &viewRenderbuffer);
	
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
	[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
	
	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
	
	if (USE_DEPTH_BUFFER) {
		glGenRenderbuffersOES(1, &depthRenderbuffer);
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
		glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
	}

	if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
		NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
		return NO;
	}
	
	return YES;
}


- (void)destroyFramebuffer {
	
	glDeleteFramebuffersOES(1, &viewFramebuffer);
	viewFramebuffer = 0;
	glDeleteRenderbuffersOES(1, &viewRenderbuffer);
	viewRenderbuffer = 0;
	
	if(depthRenderbuffer) {
		glDeleteRenderbuffersOES(1, &depthRenderbuffer);
		depthRenderbuffer = 0;
	}
}


- (void)startAnimation {
	self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
}


- (void)stopAnimation {
	self.animationTimer = nil;
}


- (void)setAnimationTimer:(NSTimer *)newTimer {
	[animationTimer invalidate];
	animationTimer = newTimer;
}


- (void)setAnimationInterval:(NSTimeInterval)interval {
	
	animationInterval = interval;
	if (animationTimer) {
		[self stopAnimation];
		[self startAnimation];
	}
}


- (void)dealloc {
	
	[self stopAnimation];
	
	if ([EAGLContext currentContext] == context) {
		[EAGLContext setCurrentContext:nil];
	}
	
	[context release];	
	[super dealloc];
}

@end
