// InterConvert -- converts internal formats

#include <proto/dos.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "RoutePlanner.h"

BOOL OpenDatabase(char *filename);
BOOL SaveDatabase(char *filename);
BOOL RedoMemory(ULONG NeededCityEntries, ULONG NeededRouteEntries);

ULONG cdcount, rdcount;

APTR memptr;

struct OldCityData *cd;
struct OldRouteData *rd;

struct NewCityData *ncd;
struct NewRouteData *nrd;

BOOL OpenDatabase(char *filename)
{
  APTR tmemptr;
  BPTR fhandle;
  __aligned struct FileInfoBlock fib;
  ULONG *temp;
  
  fhandle=Open(filename,MODE_OLDFILE);
  if(!fhandle) return FALSE;
  
  if(!ExamineFH(fhandle,&fib))
    {
    Close(fhandle);
    return FALSE;
    }
  
  tmemptr=malloc(fib.fib_Size);
  if(!tmemptr)
    {
    Close(fhandle);
    return FALSE;
    }
  
  FRead(fhandle,tmemptr,1,fib.fib_Size);
  Close(fhandle);
  
  temp=(ULONG *)tmemptr;
  if((*temp)!='RPLN')
    {
    return FALSE;
    }
  
  memptr=tmemptr;
  
  cd=(struct OldCityData *)((char *)memptr+12);
  temp=(ULONG *)((char *)(cd)-4);
  cdcount=*temp;
  
  rd=(struct OldRouteData *)
    ((char *)memptr+(sizeof(struct OldCityData)*(cdcount)+20));
  
  temp=(ULONG *)((char *)(rd)-4);
  rdcount=*temp;
  
  return TRUE;
}

BOOL SaveDatabase(char *filename)
{
  BPTR fhandle;
  ULONG id='RPL1', cid='CITY', rid='ROAD';
  LONG err;
  
  fhandle=Open(filename,MODE_NEWFILE);
  if(!fhandle) return FALSE;
  
  SetIoErr(0L);
  FWrite(fhandle,&id,sizeof(id),1);
  err=IoErr();
  if(err)
    {
    Close(fhandle);
    return FALSE;
    }
  
  SetIoErr(0L);
  FWrite(fhandle,&cid,sizeof(cid),1);
  err=IoErr();
  if(err)
    {
    Close(fhandle);
    return FALSE;
    }
  
  SetIoErr(0L);
  FWrite(fhandle,&cdcount,sizeof(cdcount),1);
  err=IoErr();
  if(err)
    {
    Close(fhandle);
    return FALSE;
    }
  
  SetIoErr(0L);
  FWrite(fhandle,&ncd[0],sizeof(struct NewCityData),cdcount);
  err=IoErr();
  if(err)
    {
    Close(fhandle);
    return FALSE;
    }
  
  SetIoErr(0L);
  FWrite(fhandle,&rid,sizeof(rid),1);
  err=IoErr();
  if(err)
    {
    Close(fhandle);
    return FALSE;
    }
  
  SetIoErr(0L);
  FWrite(fhandle,&rdcount,sizeof(rdcount),1);
  err=IoErr();
  if(err)
    {
    Close(fhandle);
    return FALSE;
    }
  
  SetIoErr(0L);
  FWrite(fhandle,&nrd[0],sizeof(struct NewRouteData),rdcount);
  err=IoErr();
  if(err)
    {
    Close(fhandle);
    return FALSE;
    }
  
  Close(fhandle);
  return TRUE;
}

BOOL RedoMemory(ULONG NeededCityEntries, ULONG NeededRouteEntries)
{
  ncd=malloc(sizeof(struct NewCityData)*NeededCityEntries);
  nrd=malloc(sizeof(struct NewRouteData)*NeededRouteEntries);

  if(ncd && nrd) return TRUE;
  
  if(ncd) free(ncd);
  if(nrd) free(nrd);
  
  return FALSE;
}

void Convert(void)
{
  ULONG i;
  
  for(i=0;i<cdcount;i++)
    {
    memset(&ncd[i],'\0',sizeof(ncd[i]));
    
    strcpy(ncd[i].CityName,cd[i].CityName);
    strcpy(ncd[i].StateName,cd[i].StateName);
    
    ncd[i].CityID=cd[i].CityID;
    ncd[i].Intersection=cd[i].Intersection;
    ncd[i].CoordsExist=cd[i].CoordsExist;
    ncd[i].CityPos.latitude=cd[i].CityPos.latitude;
    ncd[i].CityPos.longitude=cd[i].CityPos.longitude;
    }
  
  for(i=0;i<rdcount;i++)
    {
    memset(&nrd[i],'\0',sizeof(nrd[i]));
    
    strcpy(nrd[i].Hiway,rd[i].Hiway);
    strcpy(nrd[i].Exits[0],rd[i].Exits[0]);
    strcpy(nrd[i].Exits[1],rd[i].Exits[1]);
    
    nrd[i].RouteID=rd[i].RouteID;
    nrd[i].CityID[0]=rd[i].CityID[0];
    nrd[i].CityID[1]=rd[i].CityID[1];
    nrd[i].Directions[0]=rd[i].Directions[0];
    nrd[i].Directions[1]=rd[i].Directions[1];
    nrd[i].Distance=rd[i].Distance;
    nrd[i].Speed=rd[i].Speed;
    nrd[i].SpeedCode=rd[i].SpeedCode;
    nrd[i].Units=rd[i].Units;
    }
}

int main(void)
{
  BOOL ok;
  
  ok=OpenDatabase("USA-temp3.route");
  if(ok)
    {
    ok=RedoMemory(cdcount,rdcount);
    if(ok)
      {
      Convert();
      ok=SaveDatabase("USA-temp.route");
      }
    }
  
  if(ok) printf("Success\n");
    else printf("Failure\n");
  
  return(ok ? 0 : 20);
}
