#include "scene_graph_pack.h"
#include "SceneGraph.h"
#include "create_sgp.h"
#include "TaskManager.h"
using namespace std;

SchedDefineTask(Create_SGP);

/**
 * TODO
 * 入りきらない分は SceneGraphPack を next で繋げてるので
 * node->pn をつかって sgp->node[node->pn] とかやって
 * 親？の要素を探す事は出来ないかもしれません。
 * next を辿って node->pn == とかやるのは確実だけどさ。。。
 */
static int 
//create_sgp(Polygon *sg, SceneGraphPack *sgp)
run(SchedTask *smanager, void *rbuf, void *wbuf)
{

#if !SPE_CREATE_POLYGON

    //SceneGraph *sg = (SceneGraph*)smanager->get_input(rbuf, 0);
    SceneGraph *sg = (SceneGraph*)smanager->get_param(0);
    SceneGraphPack *sgp = (SceneGraphPack*)smanager->get_param(0);
    sgp->init();

    int curNumber = 0;
    int nnpn = -1;
    SceneGraphNodePtr node;

    SceneGraph *t = sg;
    
    while(t) {
	// blocking はこれでいいのかな？
	if (curNumber >= MAX_NODE ){
	    SceneGraphPack *sgp_new =
		//(SceneGraphPack*)manager->malloc(sizeof(SceneGraphPack));
		(SceneGraphPack*)smanager->allocate(sizeof(SceneGraphPack));
	    sgp_new->init();
	    sgp->info.size = curNumber-1;
	    curNumber = 0;
	    sgp->next = sgp_new;
	    sgp = sgp_new;	    
	}

	node = &sgp->node[curNumber];
	node->init();

	for (int i = 0,d = 0,tex = 0; i < t->size; i++, d += 3, tex += 2) {
	    if (node->size >= MAX_POLYGON) {
		SceneGraphNodePtr node_new = (SceneGraphNodePtr)smanager->allocate(sizeof(SceneGraphNode));
		node_new->init();
		node->next = node_new;
		node = node_new;
		d = 0;
		tex = 0;
	    }

	    /**
	     * struct texture {
	     *   int texture_id;
	     *   float vertex[3];
	     *   float texture[2];
	     * }
	     */

	    node->vertex[d]   = t->coord_xyz[i*3];
	    node->vertex[d+1] = t->coord_xyz[i*3+1];
	    node->vertex[d+2] = t->coord_xyz[i*3+2];
	    node->texture[tex]   = t->coord_tex[i*3];
	    node->texture[tex+1] = t->coord_tex[i*3+1];
	    node->size++;
	}

	node = &sgp->node[curNumber];
	
	SceneGraphNode *p = node;
	do {
	    p->obj_pos[0] = 0;
	    p->obj_pos[1] = 0;
	    p->obj_pos[2] = 0;
	    p->obj_pos[3] = 1;
	    p->angle[0] = 0;
	    p->angle[1] = 0;
	    p->angle[2] = 0;
	    p->angle[3] = 1;
	    
	    for (int tm = 0; tm < 16; tm++) {
		p->translation[tm] = 0;
	    }
	    
	    p->id = 0;
	    p->move = 0;
	    p->interaction = 0;
	    p->self = t;
	    p->tree = scene_graph;

	    p->pn = nnpn;
	    //node->tex_addr = t->texture_image->pixels;
	    p->tex_width = t->texture_image->w;
	    p->tex_height = t->texture_image->h;
	    p = p->next;
	} while (p);
    
	if (t->children != NULL) {
	    nnpn = curNumber;
	    t = t->children;
	} else if (t->brother != NULL) {
	    nnpn = node->pn;
	    t = t->brother;
	} else {
	    while (t) {
		if (t->brother != NULL) {
		    t = t->brother;
		    break;
		} else {
		    if (t->parent == NULL) {
			t = NULL;
			break;
		    }
		    nnpn = sgp->node[nnpn].pn;
		    t = t->parent;
		}
	    }
	}
	curNumber++;
    }
    sgp->info.size = curNumber;

#endif

    return 0;
}
