//////////////////////////////////////////////////////////////////////////
//Tom Valesky
//CS-752
//Dr. Chen, instructor
//scene.cpp -- source code for the Scene class
//////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "glhdr.h"
#include "point.h"
#include "explosion.h"
#include "sceneobject.h"
#include "scene.h"
#include "util.h"

Scene::Scene(void)
{
	int i, j;

		//zero out explosion/sceneobject interaction matrix

	printf("called scene constructor\n");
	for ( i = 0; i < MAX_EXPLOSIONS; i++)
	{
		for (j = 0; j < MAX_SCENEOBJECTS; j++)
		{
			interaction_matrix[i][j] = 0;

		}
		
	}
		read_file ("init.txt");	//read initialization vars from file

}

Scene::~Scene()
{
        int i;
		printf("scene destructor called\n");
        for (i = 0; i < num_explosions; i++)
                delete (explosions[i]);
        for (i = 0; i < num_scene_objects; i++)
                delete (scene_objects[i]);

}
int Scene::move(void)
{
	int i;
        int retval = FALSE;

 //	printf("called Scene::move\n");
	for (i = 0; i < num_explosions; i++)
	{
                        //explosions[i].dump(); //debug code
                        if (explosions[i]->move())
                                retval = TRUE;

	}	
		for (i 	= 0; i < num_scene_objects; i++)
	{
                scene_objects[i]->move();
	}

        return retval;
}
void Scene::draw(void)
{
	int i;
 //	printf("called Scene::draw\n");
	for (i = 0; i < num_explosions; i++)
	{
                explosions[i]->draw();
	}	
		for (i 	= 0; i < num_scene_objects; i++)
	{
                scene_objects[i]->draw();
	}

}

void Scene::dump(void)
{
        printf("called Scene::dump()\n");
        printf("num_explosions = %d\n", num_explosions);
        printf("num_scene_objects = %d\n", num_scene_objects);
}

void Scene::read_file(char *filename)
{
        FILE *fp = NULL;
        int i;

        fp = fopen(filename, "r");
        if (fp == NULL)
                {
                printf("Can't open file %s to read\n", filename);
                exit(0);
                }
        num_explosions = read_num_explosions(fp);
        for (i = 0; i < num_explosions; i++)
                {
                explosions[i] = init_explosion(fp);//read in explosion data & create new one
                }
        num_scene_objects = read_num_scene_objects(fp);
        for (i = 0; i < num_scene_objects; i++)
                {
                scene_objects[i] = init_scene_object(fp);//read in explosion data & create new one
                }

		fclose(fp);
        
}


int Scene::read_num_explosions(FILE *fp)
{
        int retval;
		char buf[BUFSIZE];
        fgets(buf, BUFSIZE - 1, fp);
        sscanf(buf, "%d", &retval);
        return retval;
}

int Scene::read_num_scene_objects(FILE *fp)
{
        int retval;
		char buf[BUFSIZE];
        fgets(buf, BUFSIZE - 1, fp);
        sscanf(buf, "%d", &retval);
        return retval;


}
Explosion *Scene::init_explosion(FILE *fp)
{
        int num_points;
        int center_x;
        int center_y;
        int center_z;
		int countdown = -1;
        float initial_radius;
        float initial_red;
        float initial_green;
        float initial_blue;
        float initial_alpha;
        float timestep;
        float initial_velocity;
        float alpha_decrement;
        int lifetime;
        Explosion *retval;
        char buf [BUFSIZE];

        fgets(buf, BUFSIZE - 1, fp);
        sscanf(buf, "%d %d %d %d %f %f %f %f %f %f %f %f %d %d",
                        &num_points, &center_x, &center_y, &center_z,
                        &initial_radius, &initial_red, &initial_green,
                        &initial_blue,  &initial_alpha, &timestep,
                        &initial_velocity, &alpha_decrement, &lifetime, &countdown);

		printf("in scene::init_explosion; countdown = %d\n", countdown);
        retval = new Explosion(num_points, center_x, center_y, center_z,
                        initial_radius, initial_red, initial_green,
                        initial_blue,  initial_alpha, timestep,
                        initial_velocity, alpha_decrement, lifetime, countdown);
        return retval;        
}
SceneObject *Scene::init_scene_object(FILE *fp)
{
	SceneObject *retval;
	int x, y, z, object_type;
	float r, g, b, radius;
	char buf[BUFSIZE];
    fgets(buf, BUFSIZE - 1, fp);
    sscanf(buf, "%d %d %d %f %f %f %f %d", &x, &y, &z, &r, &g, &b, &radius, &object_type);

	retval = new SceneObject(x, y, z, r, g, b, radius, object_type);
	return retval;
		
}

void Scene::check_intersection(void)
{
	int i, j;
	float e_radius = 0, dist_between_centers = 0, s_radius = 0;
	float ex = 0, ey = 0, ez = 0, e_vel = 0;

	for (i = 0; i < num_explosions; i++)
	{
		for (j = 0; j < num_scene_objects; j++)
		{
			if (interaction_matrix[i][j] == 0)	//if they're not already interacting
			{
				e_radius = explosions[i]->get_radius();
				ex = explosions[i]->get_x();
				ey = explosions[i]->get_y();
				ez = explosions[i]->get_z();
				dist_between_centers = scene_objects[j]->get_distance_from(ex, ey, ez);
				if (e_radius > dist_between_centers)
				{
					printf("setting interaction between exp %d and s.o. %d\n", i, j);
					interaction_matrix[i][j] = 1; //set interaction
					e_vel = explosions[i]->get_velocity();
					scene_objects[j]->add_velocity(ex, ey, ez, dist_between_centers, e_vel);
						
				}

			}
		}
	}

}
