#include "engine.h"

ObjectMesh mesh;
ObjectMesh plane;

HSlider phi_slider;
HSlider psi_slider;
HSlider dist_slider;
HSlider velocity_slider;
HSlider damping_3_slider;
HSlider damping_4_slider;

Sound sound;

EffectParticles particles;

int press = 0;
int load = 0;
ObjectMesh rb;
ObjectMesh up_rb;
ObjectMesh up_rb1,up_rb2,up_rb3,up_rb4,up_rb5;
JointHinge joint_3;
JointHinge joint_4;

void main_loop() {
	
	PhysicSetGravity(vec3(0,0,phi_slider.getValue()));
	
	vec3 pos = vec3(20,30,20);
	
	//up_rb1.setTransform(translate(pos));
	
	vec3 vel = up_rb2.getAngularVelocity();
	float k = (velocity_slider.getValue() - vel.z) / 10;
	
	float pitch = fabs(k * 2);
	sound->setGain(pitch * 2 + 0.2);
	sound->setPitch(pitch + 0.6);
	
	sound->setPosition(up_rb5.getTransform() * vec3(0,0,0));
	sound->setVelocity(up_rb5.getVelocity() * 0.002);
	
	up_rb2.addTorque(pos,vec3(0,0,1) * 5000000 * k);
	
	joint_3.setDamping(damping_3_slider.getValue());
	joint_4.setDamping(damping_4_slider.getValue());
	
	//vec3 pos = up_rb.getTransform() * vec3(0,0,0);
	//vec3 dir = normalize(vec3(0,0,100) - pos);
	//float force = length(vec3(0,0,100) - pos);
	
	//up_rb.addForce(pos,vec3(0,0,-1) * 100000);
	
	if(press == 0 && e_mouse_button == 2) {
		
		if(EngineGetKey('z',1)) {
			rb = new ObjectMesh("sphere.mesh");
			rb.setMaterial("*","sound.mat");
			rb.setSphereCollider(rb.getRadius(-1));
			rb.setRigidBody(1000,0.8,1,0.2);
			rb.setTransform(e_imodelview * mat4(0,0,-5));
			load = 1;
		}
		
		else if(EngineGetKey('x',1)) {
			rb = new ObjectMesh("box.mesh");
			rb.setMaterial("*","sound.mat");
			rb.setBoxCollider(rb.getMax(-1) - rb.getMin(-1));
			rb.setRigidBody(1000,0.2,3,0.9);
			rb.setTransform(e_imodelview * mat4(0,0,-5));
			load = 1;
		}
		
		press = 1;
	}
	
	if(e_mouse_button == 2) {
		if(load == 1) {
			rb.setTransform(e_imodelview * mat4(0,0,-5));
		}
	}
	
	if(e_mouse_button == 0) {
		if(press == 1 && load == 1) {
			rb.addImpulse(rb.getTransform() * vec3(0,0,0),rotation(e_imodelview) * vec3(0,0,-1) * 80000);
		}
		press = 0;
	}
	
	else if(e_mouse_button != 2) press = 0;
	
	particles.setTemperature(psi_slider.getValue());
}

/*
 */
void reload() {
	ConsoleCmd("load physic.cpp");
}

void reset() {
	for(int i = 0; i < 10; i++) {
		mesh = new ObjectMesh("box_111.3ds");
		mesh->setMaterial("*","default.mat");
		mesh->setBoxCollider(mesh->getMax(-1) - mesh->getMin(-1));
		mesh->setRigidBody(100,0.3,0.7,0.7);
		mesh->setTransform(translate(vec3(-8,-6,4.1 + i * 2.1)) * rotate(vec3(1,0,0),0));
	}
	
	for(int i = 0; i < 10; i++) {
		mesh = new ObjectMesh("box_111.3ds");
		mesh->setMaterial("*","default.mat");
		mesh->setBoxCollider(mesh->getMax(-1) - mesh->getMin(-1));
		mesh->setRigidBody(100,0.7,0.7,0.7);
		mesh->setTransform(translate(vec3(-8,-9,4.1 + i * 2.1)) * rotate(vec3(1,0,0),0));
	}
	
	for(int i = 0; i < 10; i++) {
		mesh = new ObjectMesh("box_111.3ds");
		mesh->setMaterial("*","default.mat");
		mesh->setBoxCollider(mesh->getMax(-1) - mesh->getMin(-1));
		mesh->setRigidBody(100,0.3,1,0.9);
		mesh->setTransform(translate(vec3(-10,-7.5,4.1 + i * 2.1)) * rotate(vec3(1,0,0),0));
	}
	
	ObjectMesh rb = new ObjectMesh("box_111.3ds");
	rb->setMaterial("*","default.mat");
	rb->setBoxCollider(rb->getMax(-1) - rb->getMin(-1));
	rb->setRigidBody(100,0.3,1,0.9);
	rb->setTransform(translate(vec3(-9,-7.5,26)));
}

void reset_2() {
	ObjectMesh rb = new ObjectMesh("box_111.3ds");
	rb->setMaterial("*","default.mat");
	rb->setBoxCollider(rb->getMax(-1) - rb->getMin(-1));
	rb->setRigidBody(100,0.3,2,0.8);
	rb->setTransform(translate(vec3(-9,-7.5,30)));
}

/*
 */
void create_gui() {
	Window window = new Window(e_gui,10000,0);
	e_gui->addWidget(window->widget(),GUI_ALIGN_OVERLAP);
	
	VBox vbox = new VBox(e_gui,4,4);
	window->addWidget(vbox->widget(),0);
	
	phi_slider = new HSlider(e_gui,-300,0.0,-9.81 * 2);
	vbox->addWidget(phi_slider->widget(),0);
	
	psi_slider = new HSlider(e_gui,0,1000,300);
	vbox->addWidget(psi_slider->widget(),0);
	
	dist_slider = new HSlider(e_gui,1,60,40);
	vbox->addWidget(dist_slider->widget(),0);
	
	velocity_slider = new HSlider(e_gui,-10,10,0);
	vbox->addWidget(velocity_slider->widget(),0);
	
	damping_3_slider = new HSlider(e_gui,0,10000,0);
	vbox->addWidget(damping_3_slider->widget(),0);
	
	damping_4_slider = new HSlider(e_gui,0,10000,0);
	vbox->addWidget(damping_4_slider->widget(),0);
	
	Button button = new Button(e_gui,"reload",vec3(1,1,1),0);
	vbox->addWidget(button->widget(),GUI_ALIGN_RIGHT);
	GuiSetCallBack(button->widget(),GUI_CLICKED,"reload");
	
	Button button = new Button(e_gui,"reset",vec3(1,1,1),0);
	vbox->addWidget(button->widget(),GUI_ALIGN_RIGHT);
	GuiSetCallBack(button->widget(),GUI_CLICKED,"reset");
	
	Button button = new Button(e_gui,"reset 2",vec3(1,1,1),0);
	vbox->addWidget(button->widget(),GUI_ALIGN_RIGHT);
	GuiSetCallBack(button->widget(),GUI_CLICKED,"reset_2");
}

/*
 *
 */
int main() {
	
	WorldLoadMesh("plane_p.mesh");
	
	WorldCreate(100);
	
	WorldSetMaterial("*","reflection_2d.mat");
	//WorldSetMaterial("*","reflection_cube.mat");
	//WorldSetMaterial("*","default.mat");
	
	EffectLight light = new EffectLight(vec3(1.2,1,1),120,1);
	light.setTransform(vec3(25,-35,55));
	
	EffectLight light = new EffectLight(vec3(1,1.2,1),120,1);
	light.setTransform(vec3(-35,25,55));
	
	//plane = new ObjectMesh("plane_p.mesh");
	//plane->setMaterial("*","default.mat");
	//plane->setTransform(translate(vec3(0,0,0)) * rotate(vec3(1,0,0),10));
	
	//plane = new ObjectMesh("plane_p.mesh");
	//plane->setMaterial("*","default.mat");
	//plane->setTransform(translate(vec3(0,0,0)));
	
	/*
	 */
	float x = 14;
	
	ObjectMesh rb0 = new ObjectMesh("box_881.3ds");
	rb0.setMaterial("*","transparent.mat");
	rb0.setBoxCollider(rb0.getMax(-1) - rb0.getMin(-1));
	rb0.setRigidBody(2000,0.2,0.2,0.7);
	rb0.setTransform(translate(vec3(0 + x,0,8)));
	
	ObjectMesh rb1 = new ObjectMesh("box_881.3ds");
	rb1.setMaterial("*","transparent.mat");
	rb1.setBoxCollider(rb1.getMax(-1) - rb1.getMin(-1));
	rb1.setRigidBody(2000,0.2,0.2,0.7);
	rb1.setTransform(translate(vec3(0 + x,0,8 + 20)));
	
	up_rb = rb1;
	
	ObjectMesh rb2 = new ObjectMesh("box_881.3ds");
	//ObjectMesh rb2 = new ObjectMesh("sphere.mesh");
	rb2.setMaterial("*","reflection_cube.mat");
	rb2.setBoxCollider(rb2.getMax(-1) - rb2.getMin(-1));
	//rb2.setSphereCollider(rb2.getRadius(-1));
	rb2.setRigidBody(2000,0.2,0.2,0.7);
	rb2.setTransform(translate(vec3(0 + x,9,8 + 10)) * rotate(vec3(1,0,0),90));
	
	ObjectMesh rb31 = new ObjectMesh("box_881.3ds");
	rb31.setMaterial("*","transparent.mat");
	rb31.setBoxCollider(rb31.getMax(-1) - rb31.getMin(-1));
	rb31.setRigidBody(2000,0.2,0.2,0.7);
	rb31.setTransform(translate(vec3(0 + x,-9,8 + 10)) * rotate(vec3(1,0,0),90));
	
	JointHinge j0 = rb0.setJointHinge(rb2,vec3(0 + x,9,8),vec3(1,0,0));
	JointHinge j1 = rb1.setJointHinge(rb2,vec3(0 + x,9,8 + 20),vec3(1,0,0));
	
	JointHinge j2 = rb0.setJointHinge(rb31,vec3(0 + x,-9,8),vec3(1,0,0));
	JointHinge j3 = rb1.setJointHinge(rb31,vec3(0 + x,-9,8 + 20),vec3(1,0,0));
	
	j0.setDamping(100);
	j1.setDamping(100);
	j2.setDamping(100);
	j3.setDamping(100);
	
	JointSpring j = rb0.setJointSpring(rb1,vec3(0 + x,9,8),vec3(0 + x,-9,8 + 20),50,3.0);
	j.setDistance(30);
	
	//}
	
	ObjectMesh rb = new ObjectMesh("box_111.3ds");
	rb.setMaterial("*","default_bump.mat");
	rb.setBoxCollider(rb.getMax(-1) - rb.getMin(-1));
	rb.setRigidBody(2000,0.1,0.2,0.7);
	rb.setTransform(translate(vec3(8 + x,8,3)));
	rb.setJointFixed(rb0);
	
	ObjectMesh rb = new ObjectMesh("box_111.3ds");
	rb.setMaterial("*","default_bump.mat");
	rb.setBoxCollider(rb.getMax(-1) - rb.getMin(-1));
	rb.setRigidBody(2000,0.1,0.2,0.7);
	rb.setTransform(translate(vec3(-8 + x,8,3)));
	rb.setJointFixed(rb0);
	
	ObjectMesh rb = new ObjectMesh("box_111.3ds");
	rb.setMaterial("*","default_bump.mat");
	rb.setBoxCollider(rb.getMax(-1) - rb.getMin(-1));
	rb.setRigidBody(2000,0.1,0.2,0.8);
	rb.setTransform(translate(vec3(8 + x,-8,3)));
	rb.setJointFixed(rb0);
	
	ObjectMesh rb = new ObjectMesh("box_111.3ds");
	rb.setMaterial("*","default_bump.mat");
	rb.setBoxCollider(rb.getMax(-1) - rb.getMin(-1));
	rb.setRigidBody(2000,0.1,0.2,0.8);
	rb.setTransform(translate(vec3(-8 + x,-8,3)));
	rb.setJointFixed(rb0);
	
	/*
	 */
	vec3 pos = vec3(0,0,0);
	int width = 10;
	int height = 10;
	for(int z = 0; z < height; z++) {
		for(int x = 0; x < width - z; x++) {
			ObjectMesh rb = new ObjectMesh("box_111.3ds");
			rb.setMaterial("*","default_red.mat");
			rb.setBoxCollider(rb.getMax(-1) - rb.getMin(-1));
			rb.setRigidBody(200,0.3,1,0.6);
			rb.setTransform(pos + vec3(0,x * 2.02 + z * 1.01 - 8,z * 2.02) + vec3(0,0,20));
		}
	}
	
	//rb = new ObjectMesh("body.mesh");
	//rb.setMaterial("body_low","default.mat");
	//rb.setMaterial("body_low",NULL);
	//rb.setTransform(translate(vec3(-12,0,10)));
	
	vec3 pos = vec3(20,30,20);
	
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","default_blue.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(1000000,0.2,8,0.9);
	rb322.setTransform(translate(pos));
	
	up_rb1 = rb322;
	
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","sound.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(10000,0.2,1,0.2);
	rb322.setTransform(translate(pos + vec3(0,0,6)));
	
	up_rb2 = rb322;
	
	up_rb2.setJointHinge(up_rb1,pos,vec3(0,0,1));
	
	//
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","sound.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(1000,0.2,1,0.2);
	rb322.setTransform(translate(pos + vec3(-3,-3,8)) * rotate(vec3(0,0,1),45));
	
	up_rb3 = rb322;
	
	joint_3 = up_rb3.setJointHinge(up_rb2,pos + vec3(-3,-3,8),vec3(0,0,1));
	
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","sound.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(1000,0.2,1,0.2);
	rb322.setTransform(translate(pos + vec3(-4,-4,10)));
	
	up_rb4 = rb322;
	
	joint_4 = up_rb4.setJointHinge(up_rb3,pos + vec3(-4,-4,10),vec3(0,0,1));
	
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","sound.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(100,0.2,1,0.2);
	rb322.setTransform(translate(pos + vec3(-5,-5,12)));
	
	up_rb5 = rb322;
	
	up_rb5.setJointHinge(up_rb4,pos + vec3(-5,-5,12),vec3(0,0,1));
	
	//
	
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","sound.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(1000,0.2,1,0.2);
	rb322.setTransform(translate(pos + vec3(4,4,8)));
	
	up_rb3 = rb322;
	
	joint_3 = up_rb3.setJointHinge(up_rb2,pos + vec3(4,4,8),vec3(0,0,1));
	
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","sound.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(1000,0.2,1,0.2);
	rb322.setTransform(translate(pos + vec3(8,8,10)));
	
	up_rb4 = rb322;
	
	joint_4 = up_rb4.setJointHinge(up_rb3,pos + vec3(8,8,10),vec3(0,0,1));
	
	ObjectMesh rb322 = new ObjectMesh("car.3ds");
	rb322.setMaterial("*","sound.mat");
	rb322.setBoxCollider(rb322.getMax(-1) - rb322.getMin(-1));
	rb322.setRigidBody(100,0.2,1,0.2);
	rb322.setTransform(translate(pos + vec3(12,12,12)));
	
	up_rb5 = rb322;
	
	up_rb5.setJointHinge(up_rb4,pos + vec3(12,12,12),vec3(0,0,1));
	
	create_gui();
	
	PlayerSpectator spectator = new PlayerSpectator();
	spectator->setPosition(vec3(40,10,35));
	spectator->setDirection(normalize(vec3(-1,-1,-0.5)));
	spectator->setMaxVelocity(120);
	WorldSetPlayer(spectator->player());
	
	sound = new Sound("cg_motor_loop_01.wav",0);
	sound->setLooping(1);
	sound->setPosition(vec3(20,30,10));
	sound->setReferenceDistance(10);
	sound->setMaxDistance(20);
	sound->play();
	
	PhysicSetGravity(vec3(0,0,-9.8));
	
	particles = new EffectParticles(vec3(0.6,0.2,0.1),"particles.png",128,1.3,0.3,4.5);
	particles.setRotation(160);
	particles.setForce(vec3(0,0,1.1));
	particles.setTransform(translate(vec3(10,-2,10)));
	particles.setBoxEmitter(vec3(0.2,0.2,0.2));
	particles.enableEmitter();
	
	return 1;
}
