#ifndef _WINDOW_H
#define _WINDOW_H
/*=
Window management
600
**/

// Introduction
/**
Some important functions, used for window creation and managment.
**/

__rayapi void raydium_window_close (void);
/**
This function is called by Raydium, do not use.
**/

__rayapi void raydium_window_create (GLuint tx, GLuint ty, signed char rendering, char *name);
/**
You must call this function once in your program, with following arguments:

1. ##tx##, ##ty##: window size, in pixel
2. ##rendering##: window mode: ##RAYDIUM_RENDERING_*## :
##NONE##, ##WINDOW## (resizable), ##WINDOW_FIXED## (unresizable) and ##FULLSCREEN##.
3. ##name##: window's name

Raydium is using MyGLUT for window management, and MyGLUT fullscreen is not
the same between all implementations. For instance, the Linux MyGLUT does
not resize the X screen, therefore doesn't care about ##tx## and ##ty##.
But the win32 implementation did resize screen.

This design choice allows to respect usual behaviors of operating systems.

Note that user can force fullscreen using ##--fullscreen## on the command line.
**/

__rayapi void raydium_window_resize_callback (GLsizei Width, GLsizei Height);
/**
This function is automaticaly called during a window resize,
and resize OpenGL rendering space.

There is almost no reason to call this function by yourself.
**/

__rayapi void raydium_window_view_update (void);
/**
If you've changed 3D window size (clipping: raydium_projection_*),
apply to hardware with this fonction.
**/

__rayapi void raydium_window_projection_update(void);
/**
Subpart of ##raydium_window_view_update()## that does not update the GL viewport.
**/

__rayapi void raydium_window_view_perspective(GLfloat fov, GLfloat fnear, GLfloat ffar);
/**
All-in-one function: sets all "perspective" variables, and updates.
**/

#endif
5,18);
    raydium_gui_button_create("btnErrorOk",handle,35,15,"OK",btnErrorOkClick);

    return;
    }

raydium_parser_db_set("KingHill2-LastServer",server);
game_state_change(GAME_GAME);
}


void create_menu(void)
{
int handle;
char lastserver[RAYDIUM_MAX_NAME_LEN];
char defaultip[RAYDIUM_MAX_NAME_LEN];

raydium_init_cli_option_default("ip",defaultip,"127.0.0.1");
raydium_parser_db_get("KingHill2-LastServer",lastserver,defaultip);

raydium_gui_theme_load("theme-raydium2.gui");

handle=raydium_gui_window_create("menu",45,75,50,20);
raydium_gui_widget_sizes(0,0,18);
raydium_gui_label_create("lblPlayerName",handle,25,85,"Player Name :",0,0,0);
raydium_gui_widget_sizes(25,4,18);
raydium_gui_edit_create("edtPlayerName",handle,47,75,raydium_network_name_local);

raydium_gui_widget_sizes(0,0,18);
raydium_gui_label_create("lblServer",handle,32.5,55,"Server :",0,0,0);
raydium_gui_widget_sizes(25,4,18);
raydium_gui_edit_create("edtServer",handle,47,45,lastserver);

raydium_gui_widget_sizes(15,5,18);
raydium_gui_button_create("btnTraining",handle,5,15,"Training",btnTrainingClick);
raydium_gui_widget_sizes(20,5,18);
raydium_gui_button_create("btnMulti",handle,50,15,"Multiplayer",btnConnect);

}


void create_car(void)
{
int a;
int respawn;

//#define BREAK_FORCE     130
#define BREAK_FORCE     0
#define ROTFRICTION     0.0005

#ifndef IPHONEOS
#define ERP_CFM         0.1,1.0
#else
#define ERP_CFM         (0.1*10),1.0
#endif

raydium_ode_object_delete_name("WATURE");

a=raydium_ode_object_create("WATURE");
raydium_ode_object_box_add("corps",a,0.5,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,TYPE_CORPS,"jeepch.tri");
raydium_ode_element_slip_name("corps",RAYDIUM_ODE_SLIP_ICE);

raydium_ode_network_next_local_only=1;
raydium_ode_object_box_add("balancier",a,1.8,0.1,0.1,0.1,RAYDIUM_ODE_STANDARD,TYPE_BALANCIER,"");
raydium_ode_element_move_name_3f("balancier",0,0,-0.5);
raydium_ode_joint_attach_fixed_name("balanfixed","corps","balancier");

raydium_ode_object_sphere_add("pneu_ag",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
//raydium_ode_element_rotfriction_name("pneu_ag",ROTFRICTION);
raydium_ode_element_move_name_3f("pneu_ag",0.42,0.453,-0.180);
raydium_ode_joint_attach_hinge2_name("suspet_ag","corps","pneu_ag",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
raydium_ode_joint_break_force_name("suspet_ag",BREAK_FORCE);
raydium_ode_joint_suspension_name("suspet_ag",ERP_CFM);

raydium_ode_object_sphere_add("pneu_ad",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
//raydium_ode_element_rotfriction_name("pneu_ad",ROTFRICTION);
raydium_ode_element_move_name_3f("pneu_ad",0.42,-0.453,-0.180);
raydium_ode_joint_attach_hinge2_name("suspet_ad","corps","pneu_ad",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
raydium_ode_joint_break_force_name("suspet_ad",BREAK_FORCE);
raydium_ode_joint_suspension_name("suspet_ad",ERP_CFM);

raydium_ode_object_sphere_add("pneu_rg",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
//raydium_ode_element_rotfriction_name("pneu_rg",ROTFRICTION);
raydium_ode_element_move_name_3f("pneu_rg",-0.444,0.453,-0.180);
raydium_ode_joint_attach_hinge2_name("suspet_rg","corps","pneu_rg",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
raydium_ode_joint_hinge2_block_name("suspet_rg",1);
raydium_ode_joint_break_force_name("suspet_rg",BREAK_FORCE);
raydium_ode_joint_suspension_name("suspet_rg",ERP_CFM);

raydium_ode_object_sphere_add("pneu_rd",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
//raydium_ode_element_rotfriction_name("pneu_rd",ROTFRICTION);
raydium_ode_element_move_name_3f("pneu_rd",-0.444,-0.453,-0.180);
raydium_ode_joint_attach_hinge2_name("suspet_rd","corps","pneu_rd",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
raydium_ode_joint_hinge2_block_name("suspet_rd",1);
raydium_ode_joint_break_force_name("suspet_rd",BREAK_FORCE);
raydium_ode_joint_suspension_name("suspet_rd",ERP_CFM);

raydium_ode_motor_create("moteur",a,RAYDIUM_ODE_MOTOR_ENGINE);
raydium_ode_motor_attach_name("moteur","suspet_ag",1);
raydium_ode_motor_attach_name("moteur","suspet_ad",1);
raydium_ode_motor_attach_name("moteur","suspet_rg",1);
raydium_ode_motor_attach_name("moteur","suspet_rd",1);
//raydium_ode_motor_power_max_name("moteur",0.2);

raydium_ode_motor_create("direction",a,RAYDIUM_ODE_MOTOR_ANGULAR);
raydium_ode_motor_attach_name("direction","suspet_ag",0);
raydium_ode_motor_attach_name("direction","suspet_ad",0);
raydium_ode_motor_power_max_name("direction",0.2);

raydium_sound_SourcePlay(son_moteur);

respawn=raydium_random_i(0,respawn_index-1);
#ifndef DEFAULT_RESPAWN_ONLY
raydium_ode_object_move(a,respawns[respawn]);
raydium_ode_object_rotate(a,respawns[respawn]+3);
#endif

//raydium_log("%i (%i)",respawn,respawn_index);
/*raydium_log("%i | %f %f %f | %f %f %f",respawn,
                                  respawns[respawn][0],
                                  respawns[respawn][1],
                                  respawns[respawn][2],
                                  respawns[respawn][3],
                                  respawns[respawn][4],
                                  respawns[respawn][5]);*/
atm_zoom=1;
}


void hms(GLfloat t,int *h, int *m, int *s, int *ms)
{
*h=*m=0;
*ms=(t-(int)t)*1000;
*s=t;
while(*s>=60)
    {
    (*m)++;
    (*s)-=60;
    }

while(*m>=60)
    {
    (*h)++;
    (*m)-=60;
    }
}

void draw_timer(void)
{
int h2,m2,s2,ms2;


partytime-=raydium_frame_time;
if(partytime<0)
    partytime=0;

if(partytime==0)
    game_state_change(GAME_END);

hms(partytime,&h2,&m2,&s2,&ms2);
raydium_osd_printf(74,97,18,0.5,"font2.tga","^fParty %i:%02i:%02i:%03i",h2,m2,s2,ms2);
}


void display_all(void)
{
raydium_ode_draw_all(0);
if(raydium_key[GLUT_KEY_F1]) raydium_ode_draw_all(1);
}

void display(void)
{
float speed=0,direct=0;
float accel=0.2;
char tag=0;
dReal *pos;
dReal cam[3];
static float secs=0;
int i,z;


if(raydium_key_last==1027) exit(0);

raydium_clear_frame();


switch(game_state)
    {
    case GAME_GAME:

        raydium_joy_key_emul();

        direct=raydium_joy_x*0.3;

        if(raydium_joy_y>0.3)
            {
            speed=raydium_joy_y*10;
            raydium_ode_motor_power_max_name("moteur",accel);
            tag=1;
            }
        else
        if(raydium_joy_y<-0.3)
            {
            speed=raydium_joy_y*5;
            raydium_ode_motor_power_max_name("moteur",0.2 * -raydium_joy_y);
            tag=1;
            }

        if(!tag)
            {
                speed=0;
                raydium_ode_motor_power_max_name("moteur",0.05);
            }

        raydium_ode_motor_speed_name("moteur",-speed);
        raydium_ode_motor_angle_name("direction",direct);

        // get element position
        pos=raydium_ode_element_pos_get_name("corps");

        // raydium_log("%f %f",pos[2],ground_z);
#ifndef DEFAULT_RESPAWN_ONLY
        if(pos[2]<ground_z)
            {
            // raydium_log("toto");
            game_state_change(GAME_OUT);
            }
#endif


        // get position of camera in world coords
        raydium_ode_element_RelPointPos_name("corps",-1,0,0,cam);

        // correct z pos (always at top of the car, for example)
        cam[2]=pos[2]+0.5;

        // standard smooth lookat camera
        raydium_camera_smooth(cam[0],cam[1],cam[2],pos[1],-pos[2],pos[0],
                              70,0,raydium_frame_time*3);


        static_camera[0]=cam[0];
        static_camera[1]=cam[1];
        static_camera[2]=cam[2];

        display_all();
        raydium_osd_printf(3.4,96.6,35,0.5,"font2.tga","^0- %s -",raydium_network_name_local);
        raydium_osd_printf(3,97,35,0.5,"font2.tga","^f- %s -",raydium_network_name_local);


        i=raydium_network_uid;
        if(i<0) i=0;
        raydium_osd_printf(2,2,15,0.5,"font2.tga","^fscore: %i",scores[i]);

        raydium_ode_element_sound_update_name("corps",son_moteur);


        speed=raydium_ode_motor_speed_get_name("moteur",1);
        speed/=12;
        speed+=0.5;
        speed+=(raydium_random_neg_pos_1()/15);
        raydium_sound_SetSourcePitch(son_moteur,raydium_math_abs(speed));

        atm_zoom_fx();
    break;


    case GAME_OUT:
        raydium_ode_element_slip_name("corps",RAYDIUM_ODE_SLIP_DEFAULT);
        raydium_ode_motor_power_max_name("moteur",10);
        raydium_ode_motor_speed_name("moteur",0);
        raydium_ode_motor_angle_name("direction",0);
        raydium_ode_element_sound_update_name("corps",son_moteur);
        raydium_sound_SetSourcePitch(son_moteur,0.2);

        if(raydium_key_last==1032 || raydium_mouse_click==1)
            game_state_change(GAME_GAME);


        pos=raydium_ode_element_pos_get_name("corps");
        raydium_camera_smooth(static_camera[0],
                              static_camera[1],
                              static_camera[2],
                              pos[1],-pos[2],pos[0],
                              90,0,raydium_frame_time*3);

        display_all();
        raydium_osd_printf(47,53,15,0.5,"font2.tga","^f[ ^cOUT!^f ]");
    break;

    case GAME_MENU:
        secs+=raydium_frame_time;
        raydium_camera_smooth_path_to_pos(camera_file,0,0,0,secs,2*raydium_frame_time);
        display_all();
    break;

    case GAME_END:
        secs+=raydium_frame_time;
        raydium_camera_smooth_path_to_pos(camera_file,0,0,0,secs,2*raydium_frame_time);
        display_all();
        raydium_osd_printf(47,93,15,0.5,"font2.tga","^f[ ^cSCORES^f ]");
        z=85;

        for(i=0;i<RAYDIUM_NETWORK_MAX_CLIENTS;i++)
        {
            if(raydium_network_name[i][0])
            {
            raydium_osd_printf(40,z,25,0.5,"font2.tga","^f%s %i",raydium_network_name[i],scores[i]);
            z-=10;
            }
        }
    break;

    }


if(game_state==GAME_GAME || game_state==GAME_OUT)
        {
        static dReal max=0;
        dReal *torque;
        dReal *pos;
        dReal posc[3];
        dReal t;


        pos=raydium_ode_element_pos_get_name("corps");
        torque = raydium_ode_element_angularvelocity_get_name("corps");
        t=(torque[0]*torque[0]+torque[1]*torque[1]+torque[2]*torque[2]);
        if(t>max)
            max=t;
        //raydium_log("%f",max);
        // problem !
        if(t>300)
            {
            raydium_log("LIMITS !!!! %f %f %f",pos[0],pos[1],pos[2]);
//          dBodySetAngularVel(raydium_ode_element[raydium_ode_element_find("corps")].body,0,0,0);
//          dBodySetAngularVel(raydium_ode_element[raydium_ode_element_find("pneu_ag")].body,0,0,0);
//          dBodySetAngularVel(raydium_ode_element[raydium_ode_element_find("pneu_ad")].body,0,0,0);
//          dBodySetAngularVel(raydium_ode_element[raydium_ode_element_find("pneu_rg")].body,0,0,0);
//          dBodySetAngularVel(raydium_ode_element[raydium_ode_element_find("pneu_rd")].body,0,0,0);
            memcpy(posc,pos,sizeof(GLfloat)*3);
            create_car();
            raydium_ode_object_move_name("WATURE",posc);
//          pos=raydium_ode_element_pos_get_name("corps");
//          raydium_log("%f %f %f",pos[0],pos[1],pos[2]);
            }

        if(raydium_network_uid>=0)
            draw_timer();
        }

raydium_rendering_finish();

raydium_ode_network_element_send_iterative(RAYDIUM_ODE_NETWORK_OPTIMAL);
}


void netcall_remaining_time(int type, char *buff)
{
float f;
memcpy(&f,buff+RAYDIUM_NETWORK_PACKET_OFFSET,sizeof(float));

partytime=f;
//raydium_log("time synced");
}


int main(int argc, char **argv)
{
int i;
char world[256];

raydium_init_args(argc,argv);
raydium_window_create(640,480,RAYDIUM_RENDERING_FULLSCREEN,"King of the Hill 2");
raydium_compat_add(RAYDIUM_COMPAT_ODE_OBJECT_MOVE_R1099);
raydium_texture_filter_change(RAYDIUM_TEXTURE_FILTER_TRILINEAR);
raydium_projection_near=0.01;
raydium_projection_far=1000;
raydium_projection_fov=60;
raydium_window_view_update();
raydium_light_on(0);
raydium_shadow_enable();
memcpy(raydium_light_color[0],sun,raydium_internal_size_vector_float_4);
raydium_light_intensity[0]=1000000;

raydium_light_position[0][0]=50;
raydium_light_position[0][1]=150;
raydium_light_position[0][2]=200;

raydium_light_update_all(0);
raydium_background_color_change(sun[0],sun[1],sun[2],sun[3]);
raydium_fog_disable();

raydium_ode_CollideCallback=collide;
raydium_ode_AfterElementDrawCallback=draw_element_after;

raydium_register_function(C2PHP(set_world),"set_world");

if(raydium_init_cli_option("world",world))
    set_world(world);
else
    set_world("jeep_hangarl");
//set_world("jeep_hangarl");

raydium_texture_find_by_name(ATM_TEXTURE_1);
raydium_texture_find_by_name(ATM_TEXTURE_2);

raydium_sound_DefaultReferenceDistance=4.f;
son_moteur=raydium_sound_LoadWav("jeepch.wav");
create_menu();

son_fall[0]=raydium_sound_LoadWav("tutombes.wav");
son_fall[1]=raydium_sound_LoadWav("tutombes2.wav");
son_fall[2]=raydium_sound_LoadWav("tutombes3.wav");

for(i=0;i<FALL_SOUNDS;i++)
    raydium_sound_SetSourceLoop(son_fall[i],0);


// scores init
for(i=0;i<RAYDIUM_NETWORK_MAX_CLIENTS;i++)
    {
    scores[i]=0;
    raydium_network_propag_add(RAYDIUM_NETWORK_PACKET_BASE+i+1,scores+i,sizeof(short));
    }
raydium_network_netcall_add(netcall_remaining_time,NET_REMAINING,1);


game_state_change(GAME_MENU);

raydium_callback(&display);

return 0;
}