#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "OS:os.h"
#include "OS:osgbpb.h"
#include "md5.h"
#include "runimage.h"

mp3file * mp3file_list=NULL;

/*
int main(void)
{
 lib_rescan();
}
*/

extern wimp_menu * menu_complete;
extern wimp_menu * menu_ibar;

extern messagetrans_control_block mess_controlblock;

ifooter * lib_fileinfo(char * path, char * filename, char * out)
{
 FILE * mp3file;
 ifooter * i=NULL;
 char buffer[2048];
 struct MD5Context state;
 unsigned char digest[16];
 long int tohash=0x49000;
 long int hashed=0;
 long int toread=0;
 ifooter * iblock;
 int read=0, di=0, rc;
 sprintf(buffer, "%s.%s", path, filename);
 /*printf("%s\n", buffer);*/
 mp3file=fopen(buffer, "rb");
 if (mp3file==NULL) return(NULL);
 MD5Init(&state);
 while((hashed<tohash)&&(read==toread))
 {
  toread = (tohash>sizeof(buffer)) ? sizeof(buffer) : tohash;
  read = fread(buffer, 1, toread, mp3file);
  MD5Update(&state, (unsigned char *) buffer, read);
  hashed+=read;
 }
 fseek(mp3file, -sizeof(ifooter), SEEK_END);
 if(fread(buffer, sizeof(ifooter), 1, mp3file)==1)
 {
  iblock=(ifooter *) buffer;
  if(!strcmp(iblock->id, "RI1"))
  {
   i=malloc(sizeof(ifooter));
   i->filesize=iblock->filesize;
   strcpy(i->checksum, iblock->checksum);
  } else i=NULL;
 }
 fseek(mp3file, 0, SEEK_END);
 hashed=ftell(mp3file);
 fclose(mp3file);
 MD5Final(digest, &state);
 memset(buffer, 0, 200);
 for(di=0, rc=0; di<16; ++di, rc+=2)
 sprintf(&buffer[rc], "%02x", digest[di]);
 strcat(buffer, "-");
 sprintf(out, "%s%li", buffer, hashed);
 /*printf("%s\n", out);*/
 return(i);
}

void lib_rescan_init(scanprogress * s)
{
 int used;
 s->filelist=(osgbpb_info_stamped_list *) malloc(1000);
 xos_read_var_val("Riscster$MusicDir", s->mdpath, 300, 0,
                                     os_VARTYPE_STRING, &used, NULL, NULL);
 s->mdpath[used]='\0';
 xosgbpb_dir_entries_info_stamped(s->mdpath, s->filelist, 1, 0, 255, NULL,
                                                           &s->read, &s->con);
}

void lib_rescan(scanprogress * s)
{
 int i;
 char checksum[100];
 char motd_displayshare[270];
 ifooter * incom;
 mp3file * ftemp, * lt;

 if(s->read!=0)
 {
  if(s->filelist->info[0].file_type==0x1ad)
  {
   ftemp=malloc(sizeof(mp3file));
   ftemp->next=NULL;
   /*printf("%s\n", filelist->info[0].name);*/
   incom = lib_fileinfo(s->mdpath, s->filelist->info[0].name, checksum);
   sprintf(motd_displayshare, "Sharing: %s", s->filelist->info[0].name);
   motd_addline(motd_displayshare);
   if(incom!=NULL)
   {
    ftemp->stat=incomplete;
    strcpy(ftemp->checksum, incom->checksum);
    ftemp->fullsize=incom->filesize;
    /*printf("MD5: %s   Size: %d\n", incom->checksum, incom->filesize);*/
    free(incom);
   }
   else
   {
    ftemp->stat=complete;
    strcpy(ftemp->checksum, checksum);
   }
   strcpy(ftemp->filename, s->filelist->info[0].name);
   ftemp->size=s->filelist->info[0].size;
   lt=mp3file_list;
   if(lt==NULL)
   {
    mp3file_list=ftemp;
   }
   else
   {
    while (lt->next!=NULL) lt=lt->next;
    lt->next=ftemp;
   }
  }
 }
 xosgbpb_dir_entries_info_stamped(s->mdpath, s->filelist, 1, s->con, 255, NULL,
                                                          &s->read, &s->con);
 if (s->con==-1)
 {
  free(s->filelist);
  lib_completemenu();
 }
}

void lib_writefooter(transfer * dl)
{
 ifooter foot;
 strcpy(foot.id, "RI1");
 foot.filesize=dl->totalsize;
 strcpy(foot.checksum, dl->checksum);
 fwrite(&foot, sizeof(ifooter), 1, dl->filehandle);
}

void lib_close()
{
 mp3file * i, * oi;
 i=mp3file_list;
 while (i!=NULL)
 {
  oi=i;
  i=i->next;
  free(oi);
 }
 mp3file_list=NULL;
}

void lib_completemenu()
{
 mp3file * i;
 wimp_menu_entry * ent;
 int numal=0, count=0;
 char buffer[20];
 char * out;
 i=mp3file_list;
 while (i!=NULL)
 {
  if(i->stat==incomplete) numal++;
  i=i->next;
 }
 if (numal==0) return;
 menu_complete=malloc(sizeof(wimp_menu)+(sizeof(wimp_menu_entry)*numal));
 error(xmessagetrans_lookup(&mess_controlblock, "COMPMENUT", buffer, 20,
                            NULL, NULL, NULL, NULL, &out, NULL));
 strcpy(menu_complete->title_data.text, out);
 standardmen(menu_complete);
 ent=(wimp_menu_entry *) &menu_complete->entries;
 i=mp3file_list;
 count=0;
 while (i!=NULL)
 {
  if (i->stat==incomplete)
  {
   wimp_menu_entry temp;
   i->menu=count;
   count++;
   temp.menu_flags = (count==numal)? wimp_MENU_LAST : 0;
   temp.sub_menu=NULL;
   temp.icon_flags=0x7000021|wimp_ICON_INDIRECTED;
   temp.data.indirected_text.text=i->filename;
   temp.data.indirected_text.size = strlen(i->filename);
   memcpy(ent++, &temp, sizeof(wimp_menu_entry));
  }
  i=i->next;
 }
 ent = (wimp_menu_entry *) &menu_ibar->entries;
 (ent+4)->sub_menu=menu_complete;
}

