#ifndef INCLUDED_SCENE_GRAPH
#define INCLUDED_SCENE_GRAPH

#include "polygon.h"
#include "Pad.h"
#include "TaskManager.h"
#include "texture.h"
class SceneGraph;

//typedef void (*move_func)(SceneGraph* node, int screen_w, int screen_h);
typedef void (*move_func)(SceneGraph* node, void *sgroot, int screen_w, int screen_h);
//typedef void (*collision_func)(SceneGraph* node, int screen_w, int screen_h,
//                               SceneGraph* tree);
typedef void (*collision_func)(SceneGraph* node, void *sgroot, int screen_w, int screen_h,
                               SceneGraph* tree);
typedef void (*create_sg_func)(void *sgroot, void *property, void *update_property);
typedef SceneGraph* SceneGraphPtr;

class SceneGraph : public Polygon {
public:
    SceneGraph(TaskManager *manager);
    SceneGraph(TaskManager *manager, xmlNodePtr surface);
    SceneGraph(SceneGraphPtr orig);
    ~SceneGraph(void);

    // add
    void *sgroot;

    // Node がもつ状態変数(というべきか否か
    // xyz,angle ぐらいあればおk？
    float stack_xyz[3];
    float stack_angle[3];
    int id;
	// Objectのシーケンス番号(Linda)
	// とりあえず動かしたいので追加
	int seq, seq_rd, resend_flag;

    // task 生成用の情報
    int property_size;
    void *propertyptr;
    int move_id;
    int coll_id;
    memaddr property;
    memaddr update_property;


    // xml ファイルから生成した時のオブジェクトリスト
    SceneGraphPtr next;
    SceneGraphPtr prev;
    SceneGraphPtr last;

    // Tree Structure
    SceneGraphPtr parent;
    SceneGraphPtr brother;
    SceneGraphPtr children;
    SceneGraphPtr lastChild;

    // Tree から削除されていたら 1 をセット。default = 0
    int flag_remove;

    // SceneGraph ID (SGList.h)
    int sgid;

    // この SceneGraph は描画するものかどうか (0:しない 1:する
    int flag_drawable;

    // anime frame num
    int frame;

    // Group ID
    int gid;

    // 関数ポインタ
    move_func move;
    collision_func collision;
    create_sg_func create_sg;

    // desutroctor で呼ばれる
    void (SceneGraph::*finalize)(void);

    void init(void);
    void finalize_original(void);
    void finalize_copy(void);
    void move_execute(int screen_w, int screen_h);
    void collision_check(int screen_w, int screen_h, SceneGraphPtr tree);
    void create_sg_execute();
    void all_execute(int screen_w, int screen_h);

    void add_next(SceneGraphPtr next);
    SceneGraphPtr addChild(SceneGraphPtr child);
    SceneGraphPtr addBrother(SceneGraphPtr bro);
    SceneGraphPtr clone(TaskManager *manager);
    SceneGraphPtr clone(void *buf);
    SceneGraphPtr searchSceneGraph(const char *name);
    void set_move_collision(move_func new_move);
    void set_move_collision(collision_func new_collision);
    void set_move_collision(move_func new_move, collision_func new_collision);
    void set_move_collision(move_func new_move, collision_func new_collision, void *sgroot);
    void set_move_collision(move_func new_move, collision_func new_collision, create_sg_func new_create_sg);
    void remove(void);
    SceneGraphPtr realRemoveFromTree(SceneGraphPtr tree);
    SceneGraphPtr realRemoveFromList(SceneGraphPtr list);
    int isRemoved(void);

    static SceneGraphPtr createSceneGraph(int id);

    void translate(float x, float y, float z);
    void translateX(float x);
    void translateY(float y);
    void translateZ(float z);


    void tree_check(void);
    void print_member(void);
    void get_data(TaskManager *manager, xmlNodePtr cur);
    void delete_data(void);

    SDL_Surface* load_decode_image(char *image_name, xmlNodePtr cur);
    int makeTapestries(TaskManager *manager, SDL_Surface *texture_image, int id);
    void get_image(TaskManager *manager, xmlNodePtr cur);
};

#endif

// 帯域変数を使うのは禁止なので削除すること
// オリジナル (Linked List)
extern SceneGraphPtr scene_graph;

// 描画用 (同じオブジェクトが複数ある) Tree
extern SceneGraphPtr scene_graph_view;
