/*
Copyright (C) 2007-2010 Victor Matei Petrescu

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

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


int main()
{int i,j,nr[3000],tip[3000],obtyp[3000],cr,
     nob=0,tno, /*number of road objects, total number of objects*/
     oc;
double ttcr=0,xcr=-1.2,ycr=0,zcr=0, /*current coordinates*/
       tt[3000],x[3000],y[3000],z[3000],axdis,
       val=1.2,brd; /*distance from vehicle to road*/

FILE *fis,*ofs;
char numefis[20];

printf("Input file: ");scanf("%s",numefis);
if(!(fis=fopen(numefis,"r"))){printf("Error: Could not open file '%s'\r\n",numefis);exit(1);}
printf("Output file: ");scanf("%s",numefis);
if(!(ofs=fopen(numefis,"w"))){printf("Error: Could not open file '%s'\r\n",numefis);exit(1);}

fprintf(ofs,"background 150 140 170\r\nclfactors 1.05 0.95 0.7\r\n");
fprintf(ofs,"objtypes 32\r\n");
fprintf(ofs,"data/steer.geo data/steer.col data/noref.ref data/nocl.cld\r\n");
fprintf(ofs,"data/speed.geo data/speed.col data/noref.ref data/nocl.cld\r\n");
fprintf(ofs,"data/dmod.geo data/dmod.col data/noref.ref data/nocl.cld\r\n");
fprintf(ofs,"data/roads.geo data/roadcity.col data/roads.ref data/road.cld\r\n");
fprintf(ofs,"data/roadlw.geo data/roadcity.col data/roadlw.ref data/road.cld\r\n");
fprintf(ofs,"data/roadln.geo data/roadcity.col data/roadln.ref data/road.cld\r\n");
fprintf(ofs,"data/roadrw.geo data/roadcity.col data/roadrw.ref data/road.cld\r\n");
fprintf(ofs,"data/roadrn.geo data/roadcity.col data/roadrn.ref data/road.cld\r\n");
fprintf(ofs,"data/road25.geo data/roadcity.col data/road25.ref data/road.cld\r\n");
fprintf(ofs,"data/road50.geo data/roadcity.col data/road50.ref data/road.cld\r\n");
fprintf(ofs,"data/road75.geo data/roadcity.col data/road75.ref data/road.cld\r\n");
fprintf(ofs,"data/tunnb.geo data/tunnbcity.col data/tunn.ref data/tunnb.cld\r\n");
fprintf(ofs,"data/tunn.geo data/tunncity.col data/tunn.ref data/tunn.cld\r\n");
fprintf(ofs,"data/bridgec.geo data/bridgecity.col data/bridgstr.ref data/bridgec.cld\r\n");
fprintf(ofs,"data/bridges.geo data/bridges.col data/bridges.ref data/nocl.cld\r\n");
fprintf(ofs,"data/start.geo data/start.col data/start.ref data/nocl.cld\r\n");
fprintf(ofs,"data/light.geo data/lightnt.col data/tree.ref data/nocl.cld\r\n");
fprintf(ofs,"data/tree4.geo data/tree4.col data/tree.ref data/nocl.cld\r\n");
fprintf(ofs,"data/block1.geo data/block1nt.col data/block1.ref data/block.cld\r\n");
fprintf(ofs,"data/block2.geo data/block2nt.col data/block2.ref data/block.cld\r\n");
fprintf(ofs,"data/trs.geo data/trscity.col data/trs.ref data/trs.cld\r\n");
fprintf(ofs,"data/wind.geo data/wind.col data/wind.ref data/wind.cld\r\n");
fprintf(ofs,"data/prop.geo data/prop.col data/noref.ref data/nocl.cld\r\n");
fprintf(ofs,"data/tree2.geo data/tree2.col data/tree.ref data/tree.cld\r\n");
fprintf(ofs,"data/glider.geo data/glider.col data/noref.ref data/nocl.cld\r\n");
fprintf(ofs,"data/bridgescl.geo data/bridges.col data/bridgec.ref data/nocl.cld\r\n");
fprintf(ofs,"data/loop4r.geo data/loopblue.col data/loop4r.ref data/loop4r.cld\r\n");
fprintf(ofs,"data/loop2r.geo data/loopgreen.col data/loop2r.ref data/loop2r.cld\r\n");
fprintf(ofs,"data/loop1r.geo data/loopred.col data/loop1r.ref data/loop1r.cld\r\n");
fprintf(ofs,"data/loop4l.geo data/loopblue.col data/loop4l.ref data/loop4l.cld\r\n");
fprintf(ofs,"data/loop2l.geo data/loopgreen.col data/loop2l.ref data/loop2l.cld\r\n");
fprintf(ofs,"data/loop1l.geo data/loopred.col data/loop1l.ref data/loop1l.cld\r\n");

cr=0;
while(!feof(fis)){
  cr++;
  fscanf(fis,"%d",&nr[cr]);
  fscanf(fis,"%d",&tip[cr]);
  if((nr[cr]>0)&&(!feof(fis))){nob+=nr[cr];}
} cr--;

fprintf(ofs,"objects %d\r\n",nob+nob);
fprintf(ofs,"16 %1.2f 0 10 0 0 0 2 0\r\n",-val);
/* fprintf(ofs,"22 %1.2f 6 10 0 0 0 2 0\r\n",-val);
fprintf(ofs,"23 %1.2f 5.1 9.1 0 0 2.356 3 0\r\n",1.5+val); */

  oc=0;

  fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 5 0\r\n",21,xcr,ycr,zcr,-ttcr+3.1415927);

  for(j=1;j<=cr;j++){
    for(i=1;i<=nr[j];i++){ oc++;
      switch(tip[j]){
        case 0: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",4,xcr,ycr,zcr,-ttcr);
                ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 3: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",5,xcr,ycr,zcr,-ttcr);
                 ycr+=9.7448*sin(ttcr)-1.9383*cos(ttcr); zcr+=9.7448*cos(ttcr)+1.9383*sin(ttcr); ttcr+=-0.3926991;
                 break;
        case 4: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",6,xcr,ycr,zcr,-ttcr);
                 ycr+=9.0031*sin(ttcr)-3.7292*cos(ttcr); zcr+=9.0031*cos(ttcr)+3.7292*sin(ttcr); ttcr+=-0.7853982;
                 break;
        case 1: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",7,xcr,ycr,zcr,-ttcr);
                 ycr+=9.7448*sin(ttcr)+1.9383*cos(ttcr); zcr+=9.7448*cos(ttcr)-1.9383*sin(ttcr); ttcr+=0.3926991;
                 break;
        case 2: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",8,xcr,ycr,zcr,-ttcr);
                 ycr+=9.0031*sin(ttcr)+3.7292*cos(ttcr); zcr+=9.0031*cos(ttcr)-3.7292*sin(ttcr); ttcr+=0.7853982;
                 break;
        case 5: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",9,xcr,ycr,zcr,-ttcr);
                xcr+=0.8; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 6: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",10,xcr,ycr,zcr,-ttcr);
                xcr+=1.6; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 7: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",11,xcr,ycr,zcr,-ttcr);
                xcr+=2.4; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 8:xcr-=0.8; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",9,xcr,ycr,zcr,-ttcr+3.1415927);
                break;
        case 9:xcr-=1.6; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",10,xcr,ycr,zcr,-ttcr+3.1415927);
                break;
        case 10:xcr-=2.4; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",11,xcr,ycr,zcr,-ttcr+3.1415927);
                break;
        case 11:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",12,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 12:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",13,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 13:xcr+=0; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",12,xcr,ycr,zcr,-ttcr+3.1415927);
                break;
        case 14: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",14,xcr,ycr,zcr,-ttcr);
                xcr+=2.4; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 15: fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",15,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break;
        case 16:xcr-=2.4; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",14,xcr,ycr,zcr,-ttcr+3.1415927);
                break;
        case 17:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",26,xcr,ycr,zcr,-ttcr);
                xcr+=2.4; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                break; /*bridge climb, not start (added in version 4.0.0)*/
        case 18:xcr-=2.4; ycr+=10*sin(ttcr); zcr+=10*cos(ttcr); ttcr+=0;
                fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",26,xcr,ycr,zcr,-ttcr+3.1415927);
                break; /*bridge descend*/
        case 19:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",27,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr+=5*cos(ttcr); zcr-=5*sin(ttcr); ttcr+=0;
                break; /*loop*/
        case 20:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",28,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr+=5*cos(ttcr); zcr-=5*sin(ttcr); ttcr+=0;
                break; /*loop*/
        case 21:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",29,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr+=5*cos(ttcr); zcr-=5*sin(ttcr); ttcr+=0;
                break; /*loop*/
        case 22:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",30,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr-=5*cos(ttcr); zcr+=5*sin(ttcr); ttcr+=0;
                break; /*loop*/
        case 23:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",31,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr-=5*cos(ttcr); zcr+=5*sin(ttcr); ttcr+=0;
                break; /*loop*/
        case 24:fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 1 0\r\n",32,xcr,ycr,zcr,-ttcr);
                xcr+=0; ycr-=5*cos(ttcr); zcr+=5*sin(ttcr); ttcr+=0;
                break; /*loop*/

        default: printf("Error: Unknown type '%d'\r\n",tip[j]);exit(1);
      }
      x[oc]=xcr; y[oc]=ycr; z[oc]=zcr; tt[oc]=ttcr; obtyp[oc]=tip[j];
    }
  }

  fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 5 0\r\n",21,xcr,ycr,zcr,-ttcr);
  fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 2 0\r\n",16,xcr,ycr-10*sin(ttcr),zcr-10*cos(ttcr),-ttcr);

tno=oc;

for(i=4;i<=oc-2;i+=2){
if((obtyp[i]==11)||(obtyp[i]==12)||(obtyp[i]==13)||(obtyp[i]==14)||(obtyp[i]==15)||(obtyp[i]==16)||(obtyp[i]==17)||(obtyp[i]==18)){continue;}
if((obtyp[i+1]==11)||(obtyp[i+1]==12)||(obtyp[i+1]==13)||(obtyp[i+1]==14)||(obtyp[i+1]==15)||(obtyp[i+1]==16)||(obtyp[i+1]==17)||(obtyp[i+1]==18)){continue;}
if((obtyp[i-1]==11)||(obtyp[i-1]==12)||(obtyp[i-1]==13)||(obtyp[i-1]==14)||(obtyp[i-1]==15)||(obtyp[i-1]==16)||(obtyp[i-1]==17)||(obtyp[i-1]==18)){continue;}
if((obtyp[i]==19)||(obtyp[i+1]==19)||(obtyp[i-1]==19)||(obtyp[i+2]==19)||(obtyp[i-2]==19)){continue;}
if((obtyp[i]==20)||(obtyp[i+1]==20)||(obtyp[i-1]==20)||(obtyp[i+2]==20)||(obtyp[i-2]==20)){continue;}
if((obtyp[i]==21)||(obtyp[i+1]==21)||(obtyp[i-1]==21)||(obtyp[i+2]==21)||(obtyp[i-2]==21)){continue;}
if((obtyp[i]==22)||(obtyp[i+1]==22)||(obtyp[i-1]==22)||(obtyp[i+2]==22)||(obtyp[i-2]==22)){continue;}
if((obtyp[i]==23)||(obtyp[i+1]==23)||(obtyp[i-1]==23)||(obtyp[i+2]==23)||(obtyp[i-2]==23)){continue;}
if((obtyp[i]==24)||(obtyp[i+1]==24)||(obtyp[i-1]==24)||(obtyp[i+2]==24)||(obtyp[i-2]==24)){continue;}
j=rand();
if(j%4){cr=17;}else{cr=18;} if(!(j%5)){goto CONT;}
  if(!(j%4)){
    if((obtyp[i]==6)||(obtyp[i]==7)||(obtyp[i]==9)||(obtyp[i]==10)){goto TREE1;}
    if((obtyp[i-1]==6)||(obtyp[i-1]==7)||(obtyp[i-1]==9)||(obtyp[i-1]==10)){goto TREE1;}
    if((obtyp[i+1]==6)||(obtyp[i+1]==7)||(obtyp[i+1]==9)||(obtyp[i+1]==10)){goto TREE1;}
    brd=9;
    if((obtyp[i-1]==5)||(obtyp[i]==5)||(obtyp[i+1]==5)||(obtyp[i-1]==8)||(obtyp[i]==8)||(obtyp[i+1]==8)){goto TREE1;}
    if(j%8){cr=19;}else{cr=20;}
    axdis=14;
    tno++; fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 2 0\r\n",cr,x[i]-brd,y[i]+axdis*sin(tt[i]-1.57),z[i]+axdis*cos(tt[i]-1.57),-tt[i]+3.1416);
  goto CONT;}
TREE1:
  if(!(j%17)){cr=24;}
brd=0;
if((obtyp[i]==5)||(obtyp[i-1]==5)||(obtyp[i+1]==5)||(obtyp[i]==8)||(obtyp[i-1]==8)||(obtyp[i+1]==8)){brd=0.2;}
if((obtyp[i]==6)||(obtyp[i-1]==6)||(obtyp[i+1]==6)||(obtyp[i]==9)||(obtyp[i-1]==9)||(obtyp[i+1]==9)){brd=0.4;}
if((obtyp[i]==7)||(obtyp[i-1]==7)||(obtyp[i+1]==7)||(obtyp[i]==10)||(obtyp[i-1]==10)||(obtyp[i+1]==10)){brd=0.6;}
axdis=5.2;
tno++; fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 2 0\r\n",cr,x[i]-brd,y[i]+axdis*sin(tt[i]-1.57),z[i]+axdis*cos(tt[i]-1.57),tt[i]);

CONT:
j=rand();
if(j%4){cr=17;}else{cr=18;} if(!(j%5)){continue;}
  if(!(j%4)){
    if((obtyp[i]==6)||(obtyp[i]==7)||(obtyp[i]==9)||(obtyp[i]==10)){goto TREE2;}
    if((obtyp[i-1]==6)||(obtyp[i-1]==7)||(obtyp[i-1]==9)||(obtyp[i-1]==10)){goto TREE2;}
    if((obtyp[i+1]==6)||(obtyp[i+1]==7)||(obtyp[i+1]==9)||(obtyp[i+1]==10)){goto TREE2;}
    brd=9;
    if((obtyp[i-1]==5)||(obtyp[i]==5)||(obtyp[i+1]==5)||(obtyp[i-1]==8)||(obtyp[i]==8)||(obtyp[i+1]==8)){goto TREE2;}
    if(j%8){cr=19;}else{cr=20;}
    axdis=14;
    tno++; fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 2 0\r\n",cr,x[i]-brd,y[i]-axdis*sin(tt[i]-1.57),z[i]-axdis*cos(tt[i]-1.57),-tt[i]);
  continue;}
TREE2:
  if(!(j%17)){cr=24;}
brd=0;
if((obtyp[i]==5)||(obtyp[i-1]==5)||(obtyp[i+1]==5)||(obtyp[i]==8)||(obtyp[i-1]==8)||(obtyp[i+1]==8)){brd=0.2;}
if((obtyp[i]==6)||(obtyp[i-1]==6)||(obtyp[i+1]==6)||(obtyp[i]==9)||(obtyp[i-1]==9)||(obtyp[i+1]==9)){brd=0.4;}
if((obtyp[i]==7)||(obtyp[i-1]==7)||(obtyp[i+1]==7)||(obtyp[i]==10)||(obtyp[i-1]==10)||(obtyp[i+1]==10)){brd=0.6;}
axdis=5.2;
tno++; fprintf(ofs,"%d %1.4f %1.4f %1.4f 0 0 %1.4f 2 0\r\n",cr,x[i]-brd,y[i]-axdis*sin(tt[i]-1.57),z[i]-axdis*cos(tt[i]-1.57),tt[i]);
}


printf("Track generated.\r\n");
printf("Edit the file '%s' and replace 'objects %d' with 'objects %d'.\r\n",numefis,nob+nob,tno+4);
fclose(fis);fclose(ofs);
return 0;}
