/***************************************************************************
                          usercamera.cpp  -  description
                             -------------------
    begin                : Don Dez 15 2005
    copyright            : (C) 2005 by Krippel Harald
    email                : neuro.harald@surfeu.at
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "usercamera.h"
#include "globdefines.h"
#include <main.h>

usercamera::usercamera()
{
     mid=0;
     cbind=0;
     objtrans = NULL;

  // camera
  camtyp=2;
  kbcamrotadd='4';
  kbcamrotsub='6';
  camrotw=-90.0f;
  kbcamheightadd='8';
  kbcamheightsub='5';
  camhight= 5.0f;
  kbcamradadd='-';
  kbcamradsub='+';
  camradius=-10.0f;
  // kbd
  gox=0.0f;
  goy=0.0f;
  kbforward=0;
  kbback=0;
  kbleft=0;
  kbright=0;
}


void usercamera::update()
{

  sgVec3 up;
  float campos[3];
  sgCoord  pos;
  sgCoord  cpos;
  sgMat4   m;
  sgMat4 mcr;


    if(mid != 0 && g_ListItem[mid] != NULL)
    {
      if(g_ListItem[mid]->text(1) == "BODY")
      {
        if(g_ListItem[mid]->body != NULL)
        {
          g_ListItem[mid]->body->GetPosition (&pos);
        }
      }
      if(g_ListItem[mid]->text(1) == "BARRIER")
      {
        if(g_ListItem[mid]->barrier != NULL)
        {
          g_ListItem[mid]->barrier->GetPosition (&pos);
        }
      }
      if(g_ListItem[mid]->text(1) == "FIRE"   ||
         g_ListItem[mid]->text(1) == "CAMERA" ||
         g_ListItem[mid]->text(1) == "OBJECT"    )
      {
        if(g_ListItem[mid]->objtrans != NULL)
        {
          g_ListItem[mid]->objtrans->getTransform ( m ) ;
          sgSetCoord  ( &pos, m ) ;
        }
      }
    }


    if(cbind==0)  // Bind == 0
    {
      camtyp = 0;
//      objtrans->getTransform ( cmat ) ;
      objtrans->getTransform ( m ) ;
      sgSetCoord  ( &cpos, m ) ;
      cpos.hpr[0] += 90;  // Bug ??
      sgMakeCoordMat4 ( cmat, &cpos );
    }
    if(camtyp==1)  // TV
    {
      objtrans->getTransform ( m ) ;
      sgSetCoord  ( &cpos, m ) ;
	    campos[0] = cpos.xyz[0] + camradius * sin(camrotw*SG_DEGREES_TO_RADIANS);
	    campos[1] = cpos.xyz[1] + camradius * cos(camrotw*SG_DEGREES_TO_RADIANS);
	    campos[2] = cpos.xyz[2] + camhight;
      sgSetVec3(up,0.0f,0.0f,1.0f);
//      sgMakeLookAtMat4(cmat,(float *) campos, (float *) pos.xyz,up);
      sgMakeLookAtMat4(cmat, campos,  pos.xyz,up);
    }
    if(camtyp==2)   // 2D
    {
	    campos[0] = pos.xyz[0] + camradius * sin(camrotw*SG_DEGREES_TO_RADIANS);
	    campos[1] = pos.xyz[1] + camradius * cos(camrotw*SG_DEGREES_TO_RADIANS);
	    campos[2] = pos.xyz[2] + camhight;
      sgSetVec3(up,0.0f,0.0f,1.0f);
//      sgMakeLookAtMat4(cmat,(float *) campos, (float *) pos.xyz,up);
      sgMakeLookAtMat4(cmat, campos,  pos.xyz,up);
    }
    if(camtyp==3)   // EGO
    {
      campos[0] = pos.xyz[0];
	    campos[1] = pos.xyz[1];
	    campos[2] = pos.xyz[2];
      sgMakeRotMat4(mcr,-pos.hpr[0],pos.hpr[1],pos.hpr[2]);
      setCamera ( campos, (float *)mcr);
    }

}

void usercamera::view(Camera *context)
{
  sgMat4   m;
  sgCoord  cpos;

      if(context != NULL)
      {
        objtrans->getTransform ( m ) ;
        sgSetCoord  ( &cpos, m ) ;
        cpos.hpr[0] += 90;  // Bug ??
        sgMakeCoordMat4 ( cmat, &cpos );
        context -> setCamera(cmat);
      }
}

void usercamera::setCamera (const float pos[3], const float R[12])
{
  sgMat4 mt;
  sgMat4 m;
  sgMat4 m1;
  sgMat4 m2;


  m[0][0] = R[0] ;
  m[0][1] = R[4] ;
  m[0][2] = R[8] ;
  m[0][3] = SG_ZERO ; //x

  m[1][0] = R[1] ;
  m[1][1] = R[5] ;
  m[1][2] = R[9] ;
  m[1][3] = SG_ZERO ;  // y

  m[2][0] = R[2] ;
  m[2][1] = R[6] ;
  m[2][2] = R[10] ;
  m[2][3] = SG_ZERO ;  // z

  m[3][0] =  pos [0] ;
  m[3][1] =  pos [1] ;
  m[3][2] =  pos [2] ;

  m[3][3] =  SG_ONE ;

  sgMakeTransMat4(mt,0.0f,camradius,camhight);
  sgMakeRotMat4(m1,camrotw,0.0f,0.0f);
  sgMultMat4(m2,m,m1);
  sgMultMat4(cmat,m2,mt);
}

void usercamera::bind(const int id)
{
    int a;
    
    mid=0;
    cbind = id;
    if(id != 0)
    {
      for(a=0;a<MAX_LIST_ITEMS;a++)
      {
        if(g_ListItem[a] != NULL)
        {
          if(g_ListItem[a]->GetValue("tmpid").toInt() == id)
          {
           mid=a;
          }
        }
      }
      if(mid == 0)
      {
            fprintf ( stderr, "usercamera: There is no such Object as '%d'\n", id ) ;
            cbind =0;
      }
    }
}
void usercamera::kbd ( char key )
{

//        printf("kbd %c %x %c\n",key,key,kbforward);
        // Keyboard Play
        if( key == kbforward)
          gox = -1;

        if( key == kbback)
          gox = 1;

        if( key == kbleft)
          goy = -1;

        if( key == kbright)
          goy = 1;

        // camera
        if( key == kbcamrotadd)
          camrotw += 4;

        if( key == kbcamrotsub)
          camrotw -= 4;

        if( key == kbcamheightadd)
          camhight += 1;

        if( key == kbcamheightsub)
          camhight -= 1;

        if( key == kbcamradadd)
          camradius += 1;

        if( key == kbcamradsub)
          camradius -= 1;
}


usercamera::~usercamera()
{

}
