/*

gula 3ds viewer

return:
  0 - doslo k chybe
  1 - este nezacal
  2 - prebehol v poriadku
  3 - uz skoncil
*/

#include <iostream>
#include "api3ds.h"
#include "efekt.h"
#include "efekt_15.h"

extern int sync_num;

int efekt_15::init()
{
  start=TRUE;
  counter=ZACIATOK15*refresh;

  glClearColor (cl_r, cl_g, cl_b, 1.0);
  if (lgt) 
    {
    glEnable(GL_LIGHTING);    
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
    }
   else 
    glDisable(GL_LIGHTING);    

  if (fog) 
    {
    GLfloat fc[4] = {fg_r,fg_g,fg_b, 1.0};
    glEnable(GL_FOG);
    glFogi(GL_FOG_MODE, GL_EXP2);
    glFogfv(GL_FOG_COLOR, fc);
    glFogf(GL_FOG_DENSITY, fgd);
    }
   else glDisable(GL_FOG);    

   new_x=0.0;
   new_y=0.0;
   new_z=0.0;
   move_counter=0.0;
   uhol_counter=0.0;
   uhol=0.0;

return 1;
}

int efekt_15::load()
{
   cout << "Loading efekt15 ... ";
   FILE *stream=fopen(CFGNAME15,"r");
   if (stream==NULL) return 0;
   fscanf(stream,"mreza                %i x %i\n",&mreza_x,&mreza_y);
   fscanf(stream,"file name            %s\n",scene_name);
   fscanf(stream,"camera name          %s\n",camera_name);
   fscanf(stream,"begin                %f\n",&begin3d);
   fscanf(stream,"end                  %f\n",&end3d);
   fscanf(stream,"background color     %f,%f,%f\n",&cl_r,&cl_g,&cl_b);
   fscanf(stream,"lightning            %i\n",&lgt);
   fscanf(stream,"fog                  %i\n",&fog);
   fscanf(stream,"fog color            %f,%f,%f\n",&fg_r,&fg_g,&fg_b);
   fscanf(stream,"fog density          %f\n",&fgd);
   fscanf(stream,"visibility           %f\n",&vis);
   fscanf(stream,"minvisibility        %f\n",&minvis);
   fscanf(stream,"hfov,vfov (PI/x)     %f,%f\n",&hfov,&vfov);
   fscanf(stream,"render               %i\n",&render);
   fscanf(stream,"rays                 %i\n",&rays);
   fscanf(stream,"outline              %i\n",&obrysy);
   fscanf(stream,"outline color        %f,%f,%f\n",&ob_r,&ob_g,&ob_b);
   fscanf(stream,"outline width        %i\n",&ob_wdt);
   fscanf(stream,"object name          %s\n",object_name);
   Vector3f o,i,j,k;
   fscanf(stream,"Descent origin       (%f,%f,%f)\n",&o.x,&o.y,&o.z);
   fscanf(stream,"Descent right        (%f,%f,%f)\n",&i.x,&i.y,&i.z);
   fscanf(stream,"Descent up           (%f,%f,%f)\n",&j.x,&j.y,&j.z);
   fscanf(stream,"Descent forward      (%f,%f,%f)\n",&k.x,&k.y,&k.z);
   dkam.SetAll(o,i,j,k);

   fclose(stream);

   mreza=mreza_x*mreza_y;

   dkam.FarClipplane(vis);
   dkam.NearClipplane(minvis);
   dkam.HorizontalFOV(PI/hfov);
   dkam.VerticalFOV(PI/vfov);

   Loader3DS loader;
   sce = loader.Load(scene_name,texture_library);
   if (sce==NULL) return 0;


   tehla1=texture_library->GetOrCreate("TEHLA1.JPG");
   phong= texture_library->GetOrCreate("PHONG.JPG");
   tien=  texture_library->GetOrCreate("TIENE.JPG");

   dmat = new DmatrixOrientation<GLmatrix,GLfloat>;


   object_gula     = dynamic_cast<Object3DS*>(sce->GetObject("Gula"));
   int numver_gula = object_gula->NumVertices();
   Vertex3DS *vtx  = object_gula->Vertices();

   for (int i=numver_gula;i;i--)
     {
     float x=0.5+(vtx->z*0.005);
     float y=fabs(atan2(vtx->x,vtx->y)*(1.0/PI));
     vtx->s=y;
     vtx->t=x;
     vtx++;
     }

   StenaVx *vetes;
   vetes=vtx_stena1;

   float x=-800.0;
   float y=-100.0;
   float z=-100.0;

   for (int j=0;j<mreza_y;j++)
     {
     for (int i=0;i<mreza_x;i++)
       {
       vetes->x=x;
       vetes->y=y;
       vetes->z=z;
       x+=1600.0/(mreza_x-1);
       vetes++;
       }
     x=-800.0;
     z+=900.0/(mreza_y-1);
     }


   vetes=vtx_stena2;
   x=-800.0;
   y=-100.0;
   z=-100.0;
   for (int j=0;j<mreza_y;j++)
     {
     for (int i=0;i<mreza_x;i++)
       {
       vetes->x=x;
       vetes->y=y;
       vetes->z=z;
       x+=1600.0/(mreza_x-1);
       vetes++;
       }
     x=-800.0;
     y+=900.0/(mreza_y-1);
     }


   cout << "ok!"<<endl;
return 1;
}

int efekt_15::free()
{
return 1;
}

int efekt_15::update()
{

move_counter+=0.01;
uhol_counter+=0.003;
uhol+=0.01;

return 1;
}


int efekt_15::go(double t)
{
if (t<ZACIATOK15) return 1;
if (t<begin3d) return 1;
if (end) return 3;
if (counter>=KONIEC15*refresh) return free();

if (!start) if (!init()) return 0;

int cur_frm=(int)(t*refresh);
if (cur_frm>KONIEC15*refresh) cur_frm=int(KONIEC15*refresh);
if (cur_frm>counter)
  while (counter<cur_frm)
    {
    counter++;
    if (counter<KONIEC15*refresh) update();
    }
if (counter>=KONIEC15*refresh) return free();


//tu sa kresli->

  float frejm=(t-begin3d)/(end3d-begin3d);
  kam = sce->GetCamera(camera_name);
  kam->FarClipplane(vis);
  kam->NearClipplane(minvis);
  kam->HorizontalFOV(PI/hfov);
  kam->VerticalFOV(PI/vfov);
  kam->GL(frejm);
//    dkam.GL();

//posun
   new_x=300*sin(0.8*move_counter);
   new_y=fabs (300*cos(move_counter));
   new_z=fabs(300*sin(2.77*move_counter));
//vyrata os, okolo ktorej sa otaca
   alfa=PI*sin(uhol_counter);
   beta=PI*cos(uhol_counter);
   gama=PI*sin(PI*cos(uhol_counter));
   float sa=sin(alfa),sb=sin(beta),sg=sin(gama);
   float ca=cos(alfa),cb=cos(beta),cg=cos(gama);
   Vector3f os(ca*cg+sa*sb*sg , ca*cb , cb*cg);
   float osl = (1.0/sqrt(os.x*os.x + os.y*os.y + os.z*os.z));
   os*=osl;
//nastavi transformacie gule
   dmat->Orientation(uhol, os.x,os.y,os.z);
   dmat->Translation(new_x,new_y,new_z);
   object_gula->CoordinateSystem(dmat);
   mat=dmat->operator()();
   mat.OrthoInverse();
   float l,x,y,xx,yy,zz,ww=1.0;


   StenaVx *vtx;

   vtx=vtx_stena1;
   for (int i=mreza;i;i--)
     {
     xx=vtx->x;
     yy=vtx->y;
     zz=vtx->z;
     mat.MultVertex4f(xx,yy,zz,ww);
     l=100.0/sqrt(xx*xx+yy*yy+zz*zz);
     x=0.5+(l*zz*0.005);
     y=fabs(atan2(xx,yy)*(1.0/PI));
     vtx->s=y;
     vtx->t=x;
     vtx++;
     }

   vtx=vtx_stena2;
   for (int i=mreza;i;i--)
     {
     xx=vtx->x;
     yy=vtx->y;
     zz=vtx->z;
     mat.MultVertex4f(xx,yy,zz,ww);
     l=100.0/sqrt(xx*xx+yy*yy+zz*zz);
     x=0.5+(l*zz*0.005);
     y=fabs(atan2(xx,yy)*(1.0/PI));
     vtx->s=y;
     vtx->t=x;
     vtx++;
     }

   tien->GL();

   StenaVx *vtx1,*vtx2;

   glDisable(GL_DEPTH_TEST);
   vtx1=vtx_stena1;
   vtx2=vtx_stena1+mreza_x;
   for (int j=0;j<mreza_y-1;j++)
     {
     glBegin(GL_QUAD_STRIP);
     glColor3f(1.0,1.0,1.0);
     for (int i=0;i<mreza_x;i++)
       {
       glTexCoord2f( vtx1->s , vtx1->t);
       glVertex3f( vtx1->x , vtx1->y , vtx1->z );
       glTexCoord2f( vtx2->s , vtx2->t);
       glVertex3f( vtx2->x , vtx2->y , vtx2->z );
       vtx1++;	   
       vtx2++;	   
       }
     glEnd();
     }

   vtx1=vtx_stena2;
   vtx2=vtx_stena2+mreza_x;
   for (int j=0;j<mreza_y-1;j++)
     {
     glBegin(GL_QUAD_STRIP);
     for (int i=0;i<mreza_x;i++)
       {
       glTexCoord2f( vtx1->s , vtx1->t);
       glVertex3f( vtx1->x , vtx1->y , vtx1->z );
       glTexCoord2f( vtx2->s , vtx2->t);
       glVertex3f( vtx2->x , vtx2->y , vtx2->z );
       vtx1++;	   
       vtx2++;	   
       }
     glEnd();
     }

   glColor3f(0.5,0.5,0.5);

   glEnable(GL_BLEND);
   glBlendFunc(GL_ONE,GL_ONE);
   tehla1->GL();
   glBegin(GL_QUADS);
    glTexCoord2f(0.01,0.01);
    glVertex3f( s1xmin ,s1ymax, s1zmin );
    glTexCoord2f(0.01,0.99);
    glVertex3f( s1xmin ,s1ymax, s1zmax );
    glTexCoord2f(0.99,0.99);
    glVertex3f( s1xmax ,s1ymax, s1zmax );
    glTexCoord2f(0.99,0.01);
    glVertex3f( s1xmax ,s1ymax, s1zmin );
   glEnd();

   glBegin(GL_QUADS);
    glTexCoord2f(0.01,0.01);
    glVertex3f( s2xmin, s2ymin, s2zmax);
    glTexCoord2f(0.01,0.99);             
    glVertex3f( s2xmin, s2ymax, s2zmax);
    glTexCoord2f(0.99,0.99);             
    glVertex3f( s2xmax, s2ymax, s2zmax);
    glTexCoord2f(0.99,0.01);             
    glVertex3f( s2xmax, s2ymin, s2zmax);
   glEnd();

   glColor3f(1.0,1.0,1.0);

   glBlendFunc(GL_ZERO,GL_SRC_COLOR);
   phong->GL();
   glBegin(GL_QUADS);
    glTexCoord2f(0.01,0.01);
    glVertex3f( s1xmin-prsh, s1ymax, s1zmin);
    glTexCoord2f(0.01,0.99);
    glVertex3f( s1xmin-prsh, s1ymax, s1zmax+prsh);
    glTexCoord2f(0.99,0.99);
    glVertex3f( s1xmax+prsh, s1ymax, s1zmax+prsh);
    glTexCoord2f(0.99,0.01);
    glVertex3f( s1xmax+prsh, s1ymax, s1zmin);

    glTexCoord2f(0.01,0.01);
    glVertex3f( s2xmin-prsh, s2ymin, s2zmax);
    glTexCoord2f(0.01,0.99);                
    glVertex3f( s2xmin-prsh, s2ymax+prsh, s2zmax);
    glTexCoord2f(0.99,0.99);                
    glVertex3f( s2xmax+prsh, s2ymax+prsh, s2zmax);
    glTexCoord2f(0.99,0.01);                
    glVertex3f( s2xmax+prsh, s2ymin, s2zmax);
   glEnd();
   glBlendFunc(GL_ONE,GL_ONE);

   sce->Render();
//<-
return 2;
}
