#import "Camera.h"

#import <OpenGLES/ES1/gl.h>

#import "Matrix.h"

@implementation Camera

#define CAMERA_ROTATION_SPEED (M_PI * 0.001f)
#define DISTANCE_MINIMUM 1.0f
#define DISTANCE_MAXIMUM 100.0f

- (id) init {
  self = [super init];
  if (self == nil) {
    return nil;
  }
  
  origin.x = 0.0f;
  origin.y = 0.0f;
  origin.z = 0.0f;
  
  distance = 8.0f;
  
  position.x = 0.0f;
  position.y = 0.0f;
  position.z = distance;
  actualPosition = position;
  
  Quaternion_loadIdentity(&orientation);
  actualOrientation = orientation;
  
  return self;
}

- (void) run {
  actualPosition.x = (((actualPosition.x * 9.0f) + position.x) * 0.1f);
  actualPosition.y = (((actualPosition.y * 9.0f) + position.y) * 0.1f);
  actualPosition.z = (((actualPosition.z * 9.0f) + position.z) * 0.1f);
  actualOrientation = Quaternion_slerp(actualOrientation, orientation, 0.1f);
}

- (void) apply {
	Matrix matrix;
	
	matrix = Quaternion_toMatrix(Quaternion_inverted(actualOrientation));
	glMultMatrixf(matrix.m);
	glTranslatef(-actualPosition.x, -actualPosition.y, -actualPosition.z);
}

- (void) rotate: (Quaternion) rotation {
  Quaternion_multiply(&orientation, rotation);
}

- (Vector) position {
  return position;
}

- (void) setPosition: (Vector) inPosition {
  position = inPosition;
}

- (void) setPositionImmediate: (Vector) inPosition {
  position = inPosition;
  actualPosition = inPosition;
}

- (Quaternion) orientation {
  return orientation;
}

- (void) setOrientation: (Quaternion) inOrientation {
  orientation = inOrientation;
}

- (void) setOrientationImmediate: (Quaternion) inOrientation {
  orientation = inOrientation;
  actualOrientation = inOrientation;
}

@end
