#import "MyOpenGLView.h"
#include <OpenGL/OpenGL.h>
@implementation MyOpenGLView
- (id) init {
	self = [super init];
	if (self != nil) {
		rot=0;
		x = 0;
		y = 0;

	}
	return self;
}

float bijelo[] = {1.0f, 1.0f, 1.0f, 0.0f};
float crno[] = {0.0f, 0.0f, 0.0f};
double smedje[] = {238.0 / 200.0, 100.0 / 255.0, 73.0 / 255.0};
float crveno[] = {1.0f, 0.0f, 0.0f};

static void drawAnObject ()
{
	glColor3f(1.0f, 0.85f, 0.35f);
	glBegin(GL_TRIANGLES);
	{
		glVertex3f( 0.0, 0.6, 0.0);
		glVertex3f( -0.2, -0.3, 0.0);
		glVertex3f( 0.2, -0.3 ,0.0);
	}
	glEnd();
}

void normiraj(double *v) {
	double d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
	v[0] /= d; v[1] /= d; v[2] /= d;
} // normiraj

void vprodukt(double *v, double a0, double a1, double a2,
              double b0, double b1, double b2) {
	v[0] = a1 * b2 - a2 * b1;
	v[1] = a2 * b0 - a0 * b2;
	v[2] = a0 * b1 - a1 * b0;
} // vprodukt

void kocka(double a) {
	glBegin(GL_QUADS);
    glNormal3d(0.0, 0.0, -1.0);
    glVertex3d(0.0, 0.0, 0.0); glVertex3d(0.0, a, 0.0);
    glVertex3d(a, a, 0.0); glVertex3d(a, 0.0, 0.0);
	
    glNormal3d(0.0, 0.0, 1.0);
    glVertex3d(0.0, 0.0, a); glVertex3d(a, 0.0, a);
    glVertex3d(a, a, a); glVertex3d(0.0, a, a);
	glEnd();
	
	glBegin(GL_QUAD_STRIP);
    glNormal3d(0.0, -1.0, 0.0);
    glVertex3d(0.0, 0.0, a); glVertex3d(0.0, 0.0, 0.0);
    glVertex3d(a, 0.0, a); glVertex3d(a, 0.0, 0.0);
	
    glNormal3d(1.0, 0.0, 0.0);    
    glVertex3d(a, a, a); glVertex3d(a, a, 0.0);
	
    glNormal3d(0.0, 1.0, 0.0);
    glVertex3d(0.0, a, a); glVertex3d(0.0, a, 0.0);
	
    glNormal3d(-1.0, 0.0, 0.0);
    glVertex3d(0.0, 0.0, a); glVertex3d(0.0, 0.0, 0.0);
	glEnd();
} // kocka


void kvadar(double a, double b, double c) {
	glBegin(GL_QUADS);
    glNormal3d(0.0, 0.0, 1.0);
    glVertex3d(0.0, 0.0, 0.0); glVertex3d(0.0, b, 0.0);
	glVertex3d(0, b, c);
    glVertex3d(0, 0, c);
	
    glNormal3d(0.0, 0.0, -1.0);
    glVertex3d(a, 0.0, 0); glVertex3d(a, 0.0, c);
    glVertex3d(a, b, c); glVertex3d(a, b, 0);
	glEnd();
	
	glBegin(GL_QUAD_STRIP);
    glNormal3d(0.0, 1.0, 0.0);
    glVertex3d(0.0, 0.0, 0.0); glVertex3d(a, 0.0, 0.0);
    glVertex3d(0, b, 0); glVertex3d(a, b, 0.0);
	
    glNormal3d(1.0, 0.0, 0.0);    
    glVertex3d(0, b, c); glVertex3d(a, b, c);
	
    glNormal3d(0.0, 1.0, 0.0);
    glVertex3d(0.0, 0, c); glVertex3d(a, 0, c);
	
    glNormal3d(-1.0, 0.0, 0.0);
    glVertex3d(0.0, 0.0, 0.0); glVertex3d(0.0, b, 0.0);
	glEnd();
} // kvadar


void polukugla(double R) {
	double ntheta = 20;
	double nphi=20;
	double t, r, z;
	double theta, step_theta = M_PI / ntheta;
	double r1, r2, z1, z2;
	int i;
	
	theta = M_PI / 2.0 - step_theta;
	r = R * cos(theta);
	z = R * sin(theta);
	
	for(theta = M_PI / 2.0 - 2.0 * step_theta; theta > -M_PI / 2.0;
		theta -= step_theta) {
		r1 = R * cos(theta); r2 = R * cos(theta + step_theta);
		z1 = R * sin(theta); z2 = R * sin(theta + step_theta);  
		
		glBegin(GL_QUAD_STRIP);
		t = 0.0; 
		for(i = 0; i <= nphi/2; i++) {
			glNormal3d(r2 * cos(t) / R, r2 * sin(t) / R, z2 / R);
			glVertex3d(r2 * cos(t), r2 * sin(t), z2);			
			glNormal3d(r1 * cos(t) / R, r1 * sin(t) / R, z1 / R);
			glVertex3d(r1 * cos(t), r1 * sin(t), z1);
			t += 2.0 * M_PI / nphi;
		}
		glEnd();
	}
	
} // polukugla

void kugla(double R, int nphi, int ntheta) {
	double t, r, z;
	double theta, step_theta = M_PI / ntheta;
	double r1, r2, z1, z2;
	int i;
	
	// bliÅ¾a kapica
	theta = M_PI / 2.0 - step_theta;
	r = R * cos(theta);
	z = R * sin(theta);
	glBegin(GL_TRIANGLE_FAN);
    glNormal3d(0.0, 0.0, 1.0);
    glVertex3d(0.0, 0.0, R);
    t = 0.0;
    for(i = 0; i <= nphi; i++) {
		glNormal3d(r * cos(t) / R, r * sin(t) / R, z / R);      
		glVertex3d(r * cos(t), r * sin(t), z);
		t += 2.0 * M_PI / nphi;
    }
	glEnd();
	
	// plaÅ¡t
	for(theta = M_PI / 2.0 - 2.0 * step_theta; theta > -M_PI / 2.0;
		theta -= step_theta) {
		r1 = R * cos(theta); r2 = R * cos(theta + step_theta);
		z1 = R * sin(theta); z2 = R * sin(theta + step_theta);  
		
		glBegin(GL_QUAD_STRIP);
		t = 0.0; 
		for(i = 0; i <= nphi; i++) {
			glNormal3d(r2 * cos(t) / R, r2 * sin(t) / R, z2 / R);
			glVertex3d(r2 * cos(t), r2 * sin(t), z2);
			glNormal3d(r1 * cos(t) / R, r1 * sin(t) / R, z1 / R);
			glVertex3d(r1 * cos(t), r1 * sin(t), z1);
			t += 2.0 * M_PI / nphi;
		}
		glEnd();
	}
	
	// dalja kapica
	theta = -M_PI / 2.0 + step_theta;
	r = R * cos(theta);
	z = R * sin(theta);
	glBegin(GL_TRIANGLE_FAN);
    glNormal3d(0.0, 0.0, -1.0);
    glVertex3d(0.0, 0.0, -R);
    t = 0.0;
    for(i = 0; i <= nphi; i++) {
		glNormal3d(r * cos(t) / R, r * sin(t) / R, z / R);
		glVertex3d(r * cos(t), r * sin(t), z);
		t -= 2.0 * M_PI / nphi;
    }
	glEnd();
} // kugla


void valjak (double r, double v) {
	glBegin (GL_TRIANGLE_FAN); 
	glNormal3d(0.0, 0.0, -1.0);
	glVertex3d(0.0, 0.0, v);      
	double t;
	
	for(t = 0.0; t < 2.0 * M_PI+1; t += M_PI/10) {
		glVertex3d(r * cos(t), r * sin(t),v);
	}
	glVertex3d(0.0, 0.0, v);      
	glEnd();
	
	glBegin (GL_TRIANGLE_FAN); 
	glNormal3d(0.0, 0.0, -1.0);
	glVertex3d(0.0, 0.0, 0.0);  
	for(t = 2.0 * M_PI+1; t > 0.0; t -= M_PI/10) {	
		glVertex3d(r * cos(t), r * sin(t),0);
	}
	glEnd();   
	glBegin (GL_QUAD_STRIP); 
	
	for(t = 2.0 * M_PI+1; t > 0.0; t -= M_PI/10) {		
		glNormal3d(cos(t), sin(t), 0.0);
		glVertex3d(r * cos(t), r * sin(t),0);
		glNormal3d(cos(t), sin(t), 0.0);
		glVertex3d(r * cos(t), r * sin(t),v);
	}
	glEnd();   
	
} 




void stozac(double r, double h, int n) {
	double t, s, v[] = {0.0, 0.0, 0.0};
	int i;
	
	// baza stožca
	glBegin(GL_TRIANGLE_FAN);
    glNormal3d(0.0, 0.0, 1.0); // normala je u smjeru -z za sve trokute
    glVertex3d(0.0, 0.0, 0.0); // središte baze je u ishodištu
    t = 0.0;
    for(i = 0; i <= n; i++) {
		glVertex3d(r * cos(t), r * sin(t), 0.0);
		t += 2.0 * M_PI / n;
    }
	glEnd();
	
	glBegin(GL_TRIANGLE_STRIP);
    t = 2.0 * M_PI;
    for(i = 0; i <= n; i++) {
		vprodukt(v, -r * cos(t), -r * sin(t), h, 
				 -cos(t + M_PI / 2.0), -sin(t + M_PI / 2.0), 0.0);
		normiraj(v);
		glNormal3dv(v);
		glVertex3d(r * cos(t), r * sin(t), 0.0);
		t -= M_PI / n; // samo pola koraka
		
		vprodukt(v, -r * cos(t), -r * sin(t), h, 
				 -cos(t + M_PI / 2.0), -sin(t + M_PI / 2.0), 0.0);
		normiraj(v);
		glNormal3dv(v); // vektor normale u vrhu je okomit na bazu trokuta
		glVertex3d(0.0, 0.0, h);
		t -= M_PI / n; // dopuna do punog koraka
    }
	glEnd();
} // stozac


void svjetlo0() {
	float pozicija[] = {0.0f, 0.0f, 0.0f, 1.0f};
	// četvrti parametar postavljen na 1.0f definira "positional light"
	// na poziciji koju određuju prva tri parametra
	
	glLightfv(GL_LIGHT0, GL_DIFFUSE, bijelo);
	glLightfv(GL_LIGHT0, GL_SPECULAR, crno);
	glLightfv(GL_LIGHT0, GL_POSITION, pozicija);
} // svjetlo0

-(void) drawRect: (NSRect) bounds
{
	glClearColor(0, 0, 0, 0);
	glEnable(GL_DEPTH_TEST);
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
	glEnable(GL_LIGHTING);
	svjetlo0();

	glEnable(GL_LIGHT0);
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
	glScaled(0.06, 0.06, 0.06);
	glRotated(rot,0,1,0);
	glRotated(-80, 1, 0, 0);
	glTranslated(0, 0, -4);
	
	
	glTranslated(-4,0,0);
	
	glRotated(60,1,0,0);
	valjak(1,12);
	glPushMatrix();
	glTranslated(0,0,4);
	kvadar(10,0,3);
	glPopMatrix();
	glPushMatrix();
	glTranslated(5,5,5);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, crno);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, smedje);
	
	kugla(5,50,50);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, crveno);
	
	glTranslated(0,4,0);
	valjak(1,9);
	glPopMatrix();
	glPushMatrix();
	glTranslated(5,9,5);
	glRotated(270,1,0,0);
	stozac(1,3,16);
	glTranslated(-10,0,2);
	glRotated(90,1,0,0);
	kvadar(20,0,1);
	glTranslated(10,0,10);
	glRotated(90,0,1,0);
	kvadar(20,0,1);
	glPopMatrix();
	glTranslated(10,0,0);
	valjak(1,12);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, bijelo);
	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0); 
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
	glFlush();
	glClear(GL_DEPTH_BUFFER_BIT);
}
-(void) rotate
{
	
	rot -= 2;
	[self drawRect:[self bounds]];
}
-(void) rotateLeft
{
	rot += 2;
	[self drawRect:[self bounds]];
}

-(void) resetGLView
{
	rot = 0;
	[self drawRect:[self bounds]];
}
@end