// Kartagony - network things :)

#define NET_GAME_STATE_T1		(RAYDIUM_NETWORK_PACKET_BASE+1)
#define NET_GAME_STATE_T2		(RAYDIUM_NETWORK_PACKET_BASE+2)
#define NET_GAME_STATE_T3		(RAYDIUM_NETWORK_PACKET_BASE+3)
#define NET_GAME_STATE_T4		(RAYDIUM_NETWORK_PACKET_BASE+4)
#define NET_GAME_STATE_BASE		NET_GAME_STATE_T1

#define NET_DEL_REQ			(RAYDIUM_NETWORK_PACKET_BASE+5)



typedef struct GameState
    {
    short scores[4];
    } GameState;
    
GameState game_state;


void delete_request(int elem)
{
char buff[RAYDIUM_NETWORK_PACKET_SIZE];
int nid;

nid=raydium_ode_element[elem].nid;

memcpy(buff+RAYDIUM_NETWORK_PACKET_OFFSET,&nid,sizeof(int));
raydium_network_write(NULL,raydium_network_uid,NET_DEL_REQ,buff);
}

void delete_request_callback(int type, char *buff)
{
int nid;
int elem;

memcpy(&nid,buff+RAYDIUM_NETWORK_PACKET_OFFSET,sizeof(int));

// let's look if this element is one of ours
elem=raydium_network_nid_element_find(nid);

if(elem>=0 && !raydium_ode_element[elem].distant)
    raydium_ode_element_delete(elem,1);
}

void net_init(void)
{
raydium_network_propag_add(NET_GAME_STATE_T1,&game_state.scores[0],sizeof(short));
raydium_network_propag_add(NET_GAME_STATE_T2,&game_state.scores[1],sizeof(short));
raydium_network_propag_add(NET_GAME_STATE_T3,&game_state.scores[2],sizeof(short));
raydium_network_propag_add(NET_GAME_STATE_T4,&game_state.scores[3],sizeof(short));

raydium_network_netcall_add(delete_request_callback,NET_DEL_REQ,1);
}
nts;
buffer = (*cinfo.mem->alloc_sarray)
        ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

count=cinfo.output_height-1;
while (cinfo.output_scanline < cinfo.output_height) 
    {
    jpeg_read_scanlines(&cinfo, buffer, 1);
    memcpy(to+cinfo.image_width*cinfo.output_components*(cinfo.output_height-count-1),buffer[0],row_stride);
    count--;
    }
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
}

int raydium_video_open_with_sound(char *filename, char *as, char *ogg)
{
int id;
char head[100];
int head_end;
int i,j,c;

/*
// we must find any previous load of this video
for(i=0;i<RAYDIUM_MAX_VIDEOS;i++)
    if( raydium_video_video[i].state && 
        !strcmp(raydium_video_video[i].name,filename))
            return i;
*/

id=raydium_video_find_free();

if(id<0)
    {
    raydium_log("video: ERROR no more free slot (%i max)",RAYDIUM_MAX_VIDEOS);
    return -1;
    }

raydium_video_video[id].fp=raydium_file_fopen(filename,"rb");

if(!raydium_video_video[id].fp)
    {
    raydium_log("video: ERROR: file '%s': open failed",filename);
    return -1;
    }

fread(head,90,1,raydium_video_video[id].fp);
head_end=0;
for(i=0;i<90;i++)
    if(head[i]=='|')
        {
        head_end=i;
        break;
        }

if(!head_end)
    {
    fclose(raydium_video_video[id].fp);
    raydium_log("video: ERROR: file '%s': invalid header or not a JPGS file. see docs",filename);
    return -1;
    }

head[head_end]=0;
fseek(raydium_video_video[id].fp,head_end+1,SEEK_SET);

sscanf(head,"%f %i %i %i",
&raydium_video_video[id].fps,
&raydium_video_video[id].sizex,
&raydium_video_video[id].sizey,
&raydium_video_video[id].frames_total);

raydium_video_video[id].state=1;
raydium_video_video[id].elapsed=0;
raydium_video_video[id].data=malloc(raydium_video_video[id].sizex*raydium_video_video[id].sizey*3);
raydium_video_video[id].live_id=raydium_live_texture_create(as,raydium_video_video[id].data,raydium_video_video[id].sizex,raydium_video_video[id].sizey,24);

raydium_video_video[id].offsets=malloc(sizeof(long)*raydium_video_video[id].frames_total);
for(i=0;i<raydium_video_video[id].frames_total;i++)
    {
    head[0]=0;
    j=0;
    while((c=fgetc(raydium_video_video[id].fp))!='|')
        {
        head[j++]=c;
        head[j]=0;
        }
    raydium_video_video[id].offsets[i]=atol(head);
    }

raydium_video_video[id].start=ftell(raydium_video_video[id].fp);
raydium_video_video[id].last_decoded=-1;
raydium_video_video[id].loop=1;
raydium_video_video[id].playing=1;
strcpy(raydium_video_video[id].name,filename);

raydium_log("video: %s (%i) as live texture %s (%i), %ix%i %.2f fps (%i frames)",
filename,id,as,raydium_video_video[id].live_id,
raydium_video_video[id].sizex,raydium_video_video[id].sizey,
raydium_video_video[id].fps,
raydium_video_video[id].frames_total);

if(ogg!=NULL && strlen(ogg)>0)
    {
    if(raydium_sound_load_music(ogg)<0)
        raydium_log("cannot sync '%s' audio to video '%s'",ogg,as);
    else
        raydium_video_current_with_sound=id;
    }

return id;
}


int raydium_video_open(char *filename, char *as)
{
return raydium_video_open_with_sound(filename,as,NULL);
}


void raydium_video_callback_video(int id)
{
int current;

if(!raydium_video_video[id].playing)
    return;

raydium_video_video[id].elapsed+=raydium_frame_time;

current=raydium_video_video[id].elapsed*raydium_video_video[id].fps;

if(current>=raydium_video_video[id].frames_total)
    {
    if(!raydium_video_video[id].loop)
        {
        if(raydium_video_current_with_sound==id)
            raydium_video_current_with_sound=-1;
        raydium_video_video[id].playing=0;
        return;
        }
        
    raydium_video_video[id].elapsed=0;
    current=0;
    }

if(current==raydium_video_video[id].last_decoded)
    {
    //printf("not again\n");
    return;
    }

fseek(raydium_video_video[id].fp,raydium_video_video[id].start+raydium_video_video[id].offsets[current],SEEK_SET);
raydium_video_jpeg_decompress(raydium_video_video[id].fp,raydium_video_video[id].data);

raydium_video_video[id].last_decoded=current;
raydium_live_texture_refresh(raydium_video_video[id].live_id);
}

void raydium_video_callback(void)
{
int i;

for(i=0;i<RAYDIUM_MAX_VIDEOS;i++)
    if(raydium_video_video[i].state)
        {
        raydium_video_callback_video(i);
        }
}


float raydium_video_sound_callback(void)
{
if(raydium_video_current_with_sound<0)
    return 0; // There's no video with sound right now

return raydium_video_video[raydium_video_current_with_sound].elapsed;
}

void raydium_video_delete(int id)
{
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot delete video: invalid index or name");
    return;
    }
fclose(raydium_video_video[id].fp);
free(raydium_video_video[id].offsets);
free(raydium_video_video[id].data);
raydium_video_video[id].state=0;
}

void raydium_video_delete_name(char *name)
{
raydium_video_delete(raydium_video_find(name));
}


void raydium_video_loop(int id, signed char loop)
{
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot set loop attrib: invalid index or name");
    return;
    }
raydium_video_video[id].loop=loop;
}

void raydium_video_loop_name(char *name, signed char loop)
{
raydium_video_loop(raydium_video_find(name),loop);
}

signed char raydium_video_isplaying(int id)
{
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot get playing state: invalid index or name");
    return -1;
    }
return raydium_video_video[id].playing;
}

signed char raydium_video_isplaying_name(char *name)
{
return raydium_video_isplaying(raydium_video_find(name));
}


void raydium_video_fps_change(int id, float fps)
{
float ratio;
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot change FPS: invalid index or name");
    return;
    }

ratio=raydium_video_video[id].fps/fps;
raydium_video_video[id].fps=fps;
raydium_video_video[id].elapsed*=ratio;
}

void raydium_video_fps_change_name(char *name, float fps)
{
raydium_video_fps_change(raydium_video_find(name),fps);
}

float raydium_video_elapsed(int id)
{
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot get video elapsed time: invalid index or name");
    return 0;
    }

return raydium_video_video[id].elapsed;
}

float raydium_video_elapsed_name(char *name)
{
return raydium_video_elapsed(raydium_video_find(name));
}

float raydium_video_duration(int id)
{
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot get video duration: invalid index or name");
    return 0;
    }

return raydium_video_video[id].frames_total/raydium_video_video[id].fps;
}

float raydium_video_duration_name(char *name)
{
return raydium_video_duration(raydium_video_find(name));
}

signed char raydium_video_seek(int id, float time)
{
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot seek video: invalid index or name");
    return 0;
    }

if(time<0) 
    time=0;

raydium_video_video[id].elapsed=time;
return 1;
}

signed char raydium_video_seek_name(char *name, float time)
{
return raydium_video_seek(raydium_video_find(name),time);
}

signed char raydium_video_seek_rel(int id, float time)
{
if(!raydium_video_isvalid(id))
    {
    raydium_log("video: ERROR: cannot (relative) seek video: invalid index or name");
    return 0;
    }

return raydium_video_seek(id,raydium_video_elapsed(id)+time);
}

signed char raydium_video_seek_rel_name(char *name, float time)
{
return raydium_video_seek_rel(raydium_video_find(name),time);
}