#ifndef INCLUDED_SCENE_GRAPH_ROOT
#define INCLUDED_SCENE_GRAPH_ROOT

#include "SceneGraph.h"
#include "SceneGraphArray.h"
#include "Camera.h"
#include "SceneGraphIterator.h"
#include "GTaskArray.h"
#include <sys/types.h>

typedef struct {
    caddr_t file_mmap;
    off_t size;
} st_mmap_t;

class Application;

class SceneGraphRoot;
typedef void (*regist_func)(SceneGraphRoot *sgroot);

class SceneGraphRoot {
public:
    /* Constructor, Destructor */
    SceneGraphRoot(float w, float h, TaskManager *manager);  
    ~SceneGraphRoot();

    /* Variables */
    TaskManager *tmanager;
    
    // xml から読み込んだ、オリジナルの SceneGraph
    // Static Singleton
    // SceneGraphPtr *sg_src;
    // int sg_src_length;
    SceneGraphPtr list;

    // move, collision 用の SceneGraph (tree)
    SceneGraphPtr sg_exec_tree;

    // 描画用の SceneGraph List (tree)
    SceneGraphPtr sg_draw_tree;

    // sg_exec_tree に対応する list
    SceneGraphPtr sg_available_list;

    // sg_draw_tree に対応する list
    // draw_tree は描画後削除される
    SceneGraphPtr sg_remove_list;

    SceneGraphArrayPtr sg_array1;
    SceneGraphArrayPtr sg_array2;
    SceneGraphArrayPtr sg_curArray;

    // コントローラーオブジェクト (Keyboard, Joystick, ..)
    Pad *controller;

    // カメラオブジェクト
    Camera *camera;

    // 光源のオブジェクト
    SceneGraphPtr light[4];
    int light_switch[4];
    int light_sysswitch;
    // 光源の疑似 xml file
    // 光源は4つで決め打ち。                                                         
    // 4 * lightnum (4) = 16;
    float light_vector[16];

    // SceneGraphIterator
    SceneGraphIteratorPtr iterator;

    // fd of Linda taple space
    int tid;

    // move task test flag
    int move_finish_flag;

    // 関数ポインタ
    regist_func regist;
    // application で実行する task
    HTaskPtr move_exec_task;

    // とりあえず
    int screen_w;
    int screen_h;


    /**
     * Functions
     */
    /* User API */
    void createFromXMLfile(TaskManager *manager, const char *);
    void createFromXMLmemory(TaskManager *manager, SceneGraph * node, char *data, int len);
    SceneGraphPtr createSceneGraph(int id);
    SceneGraphPtr createSceneGraph();
    SceneGraphPtr createSceneGraph(const char *name);
    int getSgid(const char *name);
    void appTaskRegist(regist_func new_regist);

    void setSceneData(SceneGraphPtr sg);
    Pad *getController();
    SceneGraphIteratorPtr getIterator();
    SceneGraphIteratorPtr getIterator(SceneGraphPtr list);
    CameraPtr getCamera();
    SceneGraphPtr getLight(int id);
    void OnLightSwitch(int id);
    void OffLightSwitch(int id);
    void OnLightSysSwitch();
    void OffLightSysSwitch();

    /* GameTaskArray 生成用 */
    GTaskArrayPtr gtask_array;
    void task_array_init(int id, int task_num, int param, int inData_num, int outData_num);
    void create_task_array();
    void task_array_finish();
    void set_gtask_array(int id, void *property, int size, PostFunction post_func);
    void set_gtask_array(int id, void *property, void* pad, int size, PostFunction post_func);
    void set_game_task(int id, void *property, int size);
    void set_game_task(int id, void *property, void *pad, int size);
    void set_move_task(SceneGraphPtr node, int move, void *property, int size);
    void set_pad_task(SceneGraphPtr node, int move, void *property, int size);

    /* Other System API */
    void allExecute(int screen_w, int screen_h);
    void lightCalc();
    void flip();
    void copyTree(SceneGraphPtr from, SceneGraphPtr to);

    // void oneExecute(int screen_w, int screen_h);
    void checkRemove();
    SceneGraphPtr getExecuteSceneGraph();
    SceneGraphPtr getDrawSceneGraph();
    void updateControllerState();
    void regist_execute();
    void move_finish();
    float* getLightVector();
    int* getLightSwitch();
    int getLightSysSwitch();

    // void speExecute(int screen_w, int screen_h);
    // void speExecute(int screen_w, int screen_h, Application *app);

    /* System API */
    void registSceneGraph(SceneGraphPtr sg);
    void registSceneGraphList(SceneGraphPtr sg);
    void addSceneGraphList(TaskManager *manager, SceneGraphPtr tmp);
    void addNext(SceneGraphPtr sg);
    void allRemove(SceneGraphPtr list);

    int getLast() ;

};

typedef SceneGraphRoot *SceneGraphRootPtr;


// 大域変数は無くすこと
//extern SceneGraphRoot *sgroot;
//extern SceneGraphRoot *sgroot_A;
//extern SceneGraphRoot *sgroot_B;

#endif

/* end */
