#include "gameview.h"

GameView::LoadMap(char *map)
{
    vcg::XmlDoc xml;
    
    xml.read(map); 

    mp.XMLRead(xml.root());
    
    //inizializza la posizione della pallina sopra la tile start della mappa caricata
    ball.init_posizione( mp.Start.first.X, mp.Map[mp.Start.first.X][mp.Start.first.Z].C, mp.Start.first.Z);

    //inizializza la posizione delle palline  nemiche
    for (int i=0;i<MAXENEMY;i++)
         if( mp.Enemys[i].first.X != -1) 
    enemy[i].init_posizione( mp.Enemys[i].first.X,mp.Map[mp.Enemys[i].first.X][mp.Enemys[i].first.Z].C,mp.Enemys[i].first.Z);

    camera.PositionCamera(ball.vet_posizione.x()+300,ball.vet_posizione.y()+300,ball.vet_posizione.z()+300,ball.vet_posizione.x(),ball.vet_posizione.y(),ball.vet_posizione.z(),   0, 1, 0);

    //=================temporizazione================
    conto_alla_rovescia = time_game;

    //=============numero vite=======================
    num_vite=3;

    //===============================================
    mp.CalcNorm(); //calcolo le normali della mappa

    //=========inizializzazione texture==============
    mp.InitTexture();

    return 0;
}

GameView::GameView(void)
{ 

    console.ListMap(".");
    if (console.filemap[0]!='*')
    LoadMap(console.filemap);
    console.ListSphere(".");
    currentmap=0;
    fps=1;
    time=0;
    timebase=0;
    frame=0;
    x=1;
    y=1;
    b_right=false;
    b_left=false;
    k=0;
    h=10;
    v=1;
    vl=1;
    hl=20;
    dt=0.1;
    sns=40;
    pause=true;
    camerafollowball=false;
    optionGraphics=TEXTURED;
    time_game=180;
    item=1;
    menu=MENU_MAIN;

    //=================temporizazione===============
    conto_alla_rovescia = time_game;

    //=============numero vite=======================
    num_vite=3;

    optionEnemy=ROBOT;
    scontrol=ROLLCONTROL;
    option_materiale=METALLO;
}

GameView::~GameView(void)
{
}

void GameView::Init(int option)

{

    glClearColor( 0.0, 0.0, 0.0, 0.0 );

    float gllight_0_pos[4]={1,1,0.0};   //posizione luce 0
    float gllight_0_dir[4]={1,0,1};   //direzione di ill. luce 0
    float specular_0[4]={0.8,0.8,0.8,0.8};            //caratteristiche luce 0
    float ambient_0[4]={0.8,0.8,0.8,0.8};         
    float diffuse_0[4]={0.8,0.8,0.8,0.8};     
    float specular[4]={0.5,0.5,0.5,0.5};          //  caratteristiche dei materiali
    float ambient[4]={0.7,0.7,0.7,0.7};   
    float diffuse[4]={0.6,0.6,0.6,0.6};     

    switch(option)

    {

     case METALLO: 

            
             specular_0[0]=1;  specular_0[1]=1; specular_0[2]=1; specular_0[3]=1;         //caratteristiche luce 0
             ambient_0[0]=0;   ambient_0[1]=0;  ambient_0[2]=0;  ambient_0[3]=1;
             diffuse_0[0]=0;   diffuse_0[0]=0;  diffuse_0[0]=0;  diffuse_0[0]=1;

             specular[0]=1;    specular[1]=1;   specular[2]=1;   specular[3]=1;           //  caratteristiche dei materiali
             ambient[0]=0;     ambient[1]=0;    ambient[2]=0;    ambient[3]=1;
             diffuse[0]=0;     diffuse[1]=0;    diffuse[2]=0;    diffuse[3]=1;

             glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,33.0);                            //settaggio brillantezza
             glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
             glEnable(GL_COLOR_MATERIAL);

          break;

     case VETRO: 
            
             specular_0[0]=1;  specular_0[1]=1; specular_0[2]=1; specular_0[3]=1;         //caratteristiche luce 0
             ambient_0[0]=0;   ambient_0[1]=0;  ambient_0[2]=0;  ambient_0[3]=1;
             diffuse_0[0]=0;   diffuse_0[0]=0;  diffuse_0[0]=0;  diffuse_0[0]=1;

             specular[0]=0.99;    specular[1]=0.91;   specular[2]=0.81;   specular[3]=1;  //  caratteristiche dei materiali
             ambient[0]=0.33;     ambient[1]=0.22;    ambient[2]=0.03;    ambient[3]=1;
             diffuse[0]=0.78;     diffuse[1]=0.57;    diffuse[2]=0.11;    diffuse[3]=1;

             glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,27.8);                            //settaggio brillantezza
             glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
             glEnable(GL_COLOR_MATERIAL);

          break;


     case PLASTICA : 
            
             specular_0[0]=1;  specular_0[1]=1; specular_0[2]=1; specular_0[3]=1;        //caratteristiche luce 0
             ambient_0[0]=0;   ambient_0[1]=0;  ambient_0[2]=0;  ambient_0[3]=1;
             diffuse_0[0]=1;   diffuse_0[0]=1;  diffuse_0[0]=1;  diffuse_0[0]=1;

             specular[0]=1;    specular[1]=1;   specular[2]=1;   specular[3]=1;          //  caratteristiche dei materiali
             ambient[0]=0;     ambient[1]=0;    ambient[2]=0;    ambient[3]=1;
             diffuse[0]=1;     diffuse[1]=1;    diffuse[2]=1;    diffuse[3]=1;

             glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,50.0);                           //settaggio brillantezza
             glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
             glEnable(GL_COLOR_MATERIAL);

          break;

      case LUMINOSO :
            
             specular_0[0]=1;  specular_0[1]=1; specular_0[2]=1; specular_0[3]=1;        //caratteristiche luce 0
             ambient_0[0]=1;   ambient_0[1]=1;  ambient_0[2]=1;  ambient_0[3]=1;
             diffuse_0[0]=1;   diffuse_0[0]=1;  diffuse_0[0]=1;  diffuse_0[0]=1;

             specular[0]=1;    specular[1]=1;   specular[2]=1;   specular[3]=1;          //  caratteristiche dei materiali
             ambient[0]=1;     ambient[1]=1;    ambient[2]=1;    ambient[3]=1;
             diffuse[0]=1;     diffuse[1]=1;    diffuse[2]=1;    diffuse[3]=1;

             glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,100.0);                          //settaggio brillantezza
        
             glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
             glEnable(GL_COLOR_MATERIAL);


          break; 

      default :      
              
            glDisable(GL_COLOR_MATERIAL);

    

    }
        

    glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE , diffuse);
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambient);
    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR ,specular);

    glLightfv(GL_LIGHT0,GL_POSITION,gllight_0_pos );
    glLightfv(GL_LIGHT0,GL_SPECULAR,specular_0 );
    glLightfv(GL_LIGHT0,GL_AMBIENT,ambient_0);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse_0);


    // Abilita il calcolo dell'illuminazione
    glEnable(GL_LIGHTING);

    // Abilita la luce GL_LIGHT0
    glEnable(GL_LIGHT0);


    // anche le normali attraversano la pipeline, quindi devono essere  
    // rinormalizzate, prima del calcolo dell'illuminazione, altrimenti 
    // il calcolo dell'illuminazione viene sbagliato.
    glEnable(GL_NORMALIZE); 
    
    // Abilita il test sullo zbuffer e quindi l'eliminazione delle 
    // superfici nascoste
    glEnable(GL_DEPTH_TEST);
                 
    mp.CalcNorm(); 

    mp.InitTexture();

    ball.setTexture(console.filesphere);
    for (int i=0; i<MAXENEMY;i++) 
    {
        enemy[i].setTexture(mp.Tex[mp.TexEnemy]);
    }
}

void GameView::setKey(int key)
{
 setSKey(key);
}

void GameView::setSKey(int key)

{

    switch (key)
    {
    case GLUT_KEY_PAGE_UP:  vl=vl-0.1;break;
    case GLUT_KEY_PAGE_DOWN: vl=vl+0.1; break;
    case GLUT_KEY_F1: glutFullScreen(); 
                      Reshape(glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
                        break;
    case GLUT_KEY_F2:  SizeViewX=800; SizeViewY=600;
                        Reshape(SizeViewX,SizeViewY);
                        glutReshapeWindow(SizeViewX,SizeViewY);
                        glutPositionWindow(50,50);
                        break;
    case GLUT_KEY_F3 :
    case 27: 
        menu=10;
        item=1;
        Pause();

                break;
    case GLUT_KEY_F4:
                    camerafollowball=!camerafollowball;
                    break;

    case GLUT_KEY_F5:

                     option_materiale = (option_materiale+1)%4;
                   
                     Init(option_materiale);
                   
                    break;
    case GLUT_KEY_UP:
                    if (pause && (item>1)) item=item-1;
                    if (!pause) {
                        moveBall(C_UP);
        
                    }
                    break;
    case GLUT_KEY_DOWN:
                    if (pause && (item<console.numitem)) item=item+1;
                    if (!pause) {moveBall(C_DOWN);}
                    break;
    case GLUT_KEY_LEFT:
       if (!pause) {moveBall(C_LEFT); }
       break;
    case GLUT_KEY_RIGHT:
       if(!pause) {moveBall(C_RIGHT);}
       break;
    case 13:    selectMenuItem(menu,item);
        break;
    }
    if (vl>M_PI-0.1) vl=M_PI-0.1;
    if (vl<0.1) vl=0.1;

}

void GameView::selectMenuItem(int m, int i)

{

    char *s;
    char str[120];
    printf("%s",console.selitem);
    if (!pause) return;
    if (m==MENU_MAP) 
       
        {
            currentmap=i-1;
            console.map[i-1].copy(str,console.map[i-1].npos);
            
            s=strstr(str,".mnm");
            s[4]='\0'; 
            LoadMap(str); 
        }

    if (m==MENU_BALL) 
    
        {

            char str[120];

            console.sphere[i-1].copy(str,console.sphere[i-1].npos);
            s=strstr(str,".jpg");
            s[4]='\0'; 
            ball.setTexture(str); 
            
        }
    else

           switch(m+i)
           
              {

                case MENU_GOAL  +   ITEM_GOAL:
                                                currentmap=currentmap+1;
                                                if (currentmap>=console.nummap) currentmap=0;
                                                console.map[currentmap].copy(str,console.map[currentmap].npos);
                                                pause=false;
                                                s=strstr(str,".mnm");
                                                s[4]='\0'; 
                                                LoadMap(str); 
                                                break;
                case MENU_TIMEOUT+  ITEM_DEAD:
                case MENU_DEAD  +   ITEM_DEAD:
                                                ball.init_posizione( mp.Start.first.X, mp.Map[mp.Start.first.X][mp.Start.first.Z].C, mp.Start.first.Z);
                                                num_vite--;
                                                pause=false;
                                                menu=MENU_MAIN;
                                                conto_alla_rovescia=time_game;
                                                item=1;
                                                if (num_vite <=0) { menu=MENU_GAMEOVER;
                                                            pause=true;}
                                                break;
                

                case MENU_GAMEOVER+ ITEM_GAMEOVER:
                                                menu=MENU_MAIN;
                                                ball.init_posizione( mp.Start.first.X, mp.Map[mp.Start.first.X][mp.Start.first.Z].C, mp.Start.first.Z);
                                                num_vite=3;
                                                currentmap=0;
                                                console.map[currentmap].copy(str,console.map[currentmap].npos);
                                                pause=false;
                                                s=strstr(str,".mnm");
                                                s[4]='\0'; 
                                                LoadMap(str); 
                                                item=1;
                                                pause=true;
                    
                                                conto_alla_rovescia=time_game;
                                                break;
                case MENU_PAUSE +   ITEM_MAIN_START:
                case MENU_MAIN  +   ITEM_MAIN_START:    pause=false;break;
                case MENU_PAUSE +   ITEM_MAIN_MAP:
                case MENU_MAIN  +   ITEM_MAIN_MAP:      menu=MENU_MAP;item=1;break;
                case MENU_PAUSE +   ITEM_MAIN_DISPLAY:
                case MENU_MAIN  +   ITEM_MAIN_DISPLAY:  menu=MENU_DISPLAY;item=1;break;
                case MENU_PAUSE +   ITEM_MAIN_CAMERA:
                case MENU_MAIN  +   ITEM_MAIN_CAMERA:   menu=MENU_CAMERA;item=1;break;
                case MENU_PAUSE +   ITEM_MAIN_GRAPHICS:
                case MENU_MAIN  +   ITEM_MAIN_GRAPHICS: menu=MENU_GRAPHICS;item=1;break;
                case MENU_PAUSE +   ITEM_MAIN_BALL:
                case MENU_MAIN  +   ITEM_MAIN_BALL:     menu=MENU_BALL;item=1;break; 
                case MENU_PAUSE +   ITEM_MAIN_CONTROL:
                case MENU_MAIN  +   ITEM_MAIN_CONTROL:  menu=MENU_CONTROL;item=1;break;
                case MENU_PAUSE +   ITEM_MAIN_TIMER:
                case MENU_MAIN  +   ITEM_MAIN_TIMER:    menu=MENU_TIMER;item=1;break;
                case MENU_PAUSE +   ITEM_EXIT:
                case MENU_MAIN  +   ITEM_EXIT:          exit(0);break;
                default: 
                case MENU_MAP   +   ITEM_MAP_BACK:      menu=MENU_MAIN; item=1;break;
                case MENU_DISPLAY+  ITEM_DISPLAY_W_640x480: 
                                                            SizeViewX=640; SizeViewY=480;
                                                            Reshape(SizeViewX,SizeViewY);
                                                            glutReshapeWindow(SizeViewX,SizeViewY);
                                                            glutPositionWindow(50,50);
                                                            break;
                case MENU_DISPLAY+  ITEM_DISPLAY_W_800x600: 
                                                            SizeViewX=800; SizeViewY=600;
                                                            Reshape(SizeViewX,SizeViewY);
                                                            glutReshapeWindow(SizeViewX,SizeViewY);
                                                            glutPositionWindow(50,50);
                                                            break;
                case MENU_DISPLAY+  ITEM_DISPLAY_W_1024x768:
                                                            SizeViewX=1024; SizeViewY=768;
                                                            Reshape(SizeViewX,SizeViewY);
                                                            glutReshapeWindow(SizeViewX,SizeViewY);
                                                            glutPositionWindow(50,50);  
                                                            break;
                case MENU_DISPLAY+  ITEM_DISPLAY_FULLSCREEN:
                                                            glutFullScreen(); 
                                                            Reshape(glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
                                                            break;
                case MENU_DISPLAY+  ITEM_DISPLAY_BACK:  menu=MENU_MAIN;item=1;break;
                case MENU_CAMERA+   ITEM_CAMERA_FOLLOW :camerafollowball=true;break;
                case MENU_CAMERA+   ITEM_CAMERA_NFOLLOW:camerafollowball=false;break;
                case MENU_CAMERA+   ITEM_CAMERA_BACK:   menu=MENU_MAIN;item=1;break;
                case MENU_BALL  +   ITEM_BALL_METAL:    Init(METALLO);break;
                case MENU_BALL  +   ITEM_BALL_GLASS:    Init(VETRO);break;
                case MENU_BALL  +   ITEM_BALL_PLASTIC:  Init(PLASTICA);break;
                case MENU_BALL  +   ITEM_BALL_SHINING:  Init(LUMINOSO);break;
                case MENU_BALL  +   ITEM_BALL_BACK:     menu=MENU_MAIN;item=1;break;
                case MENU_CONTROL+  ITEM_CONTROL_ROLL:  scontrol=ROLLCONTROL;break;
                case MENU_CONTROL+  ITEM_CONTROL_LUKE:  scontrol=LUKECONTROL;break;
                case MENU_CONTROL+ ITEM_CONTROL_SNS20:  sns=20;break;
                case MENU_CONTROL+ ITEM_CONTROL_SNS40:  sns=40;break;
                case MENU_CONTROL+ ITEM_CONTROL_SNS60:  sns=60;break;
                case MENU_CONTROL+ ITEM_CONTROL_SNS80:  sns=80;break;
                case MENU_CONTROL+  ITEM_CONTROL_BACK:  menu=MENU_MAIN;item=1;break;
                case MENU_TIMER +   ITEM_TIMER_100:     time_game=100;conto_alla_rovescia=time_game;break;
                case MENU_TIMER +   ITEM_TIMER_300:     time_game=300;conto_alla_rovescia=time_game;break;
                case MENU_TIMER +   ITEM_TIMER_600:     time_game=600;conto_alla_rovescia=time_game;break;
                case MENU_TIMER +   ITEM_TIMER_UNLIMITED:time_game=65000;conto_alla_rovescia=time_game;break;
                case MENU_TIMER +   ITEM_TIMER_BACK:    menu=MENU_MAIN;item=1;break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_TEXTURED:
                                                        optionGraphics=TEXTURED;
                                                        glEnable(GL_LIGHTING);
                                                        glEnable(GL_LIGHT0);
                                                        glTexEnvi(  GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
                                                        break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_SOLID:
                                                        optionGraphics=SOLID;
                                                        glDisable(GL_TEXTURE_2D);
                                                        glEnable(GL_LIGHTING);
                                                        glEnable(GL_LIGHT0);
                                                        break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_WIREFRAME:
                                                        glDisable(GL_TEXTURE_2D);
                                                        glDisable(GL_LIGHT0);
                                                        glDisable(GL_LIGHTING);
                                                        optionGraphics=WIREFRAME;
                                                        break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_ROBOT:optionEnemy=ROBOT;break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_NOROBOT:optionEnemy=NOROBOT;break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_BACK: menu=MENU_MAIN;item=1;break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_NORMAL:
                                                        optionGraphics=TEXTURED;
                                                        glEnable(GL_LIGHTING);
                                                        glEnable(GL_LIGHT0);
                                                        glTexEnvi(  GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
                                                        break;
                case MENU_GRAPHICS+ ITEM_GRAPHICS_ENV: menu=MENU_ENV;item=1;break;
                case MENU_ENV   +   ITEM_ENV_DEFAULT:
                                                        option_materiale=DEFAULT;
                                                        Init(option_materiale);
                                                        break;
                case MENU_ENV   +   ITEM_ENV_METAL:
                                                        option_materiale=METALLO;
                                                        Init(option_materiale);
                                                        break;  
                case MENU_ENV   +   ITEM_ENV_GLASS:
                                                        option_materiale=VETRO;
                                                        Init(option_materiale);
                                                        break;
                case MENU_ENV   +   ITEM_ENV_PLASTIC:
                                                        option_materiale=PLASTICA;
                                                        Init(option_materiale);
                                                        break;
                case MENU_ENV   +   ITEM_ENV_SHINING:
                                                        option_materiale=LUMINOSO;
                                                        Init(option_materiale);
                                                        break;
             
                }


}

void GameView::setSKeyUp(int key)
{}


void GameView::Reshape(int w, int h)
{

    SizeViewX=w;
    SizeViewY=h;
    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if(SizeViewY == 0)  SizeViewX = 1;

    float ratio = 1.0*  SizeViewX / SizeViewY;

    // Reset the coordinate system before modifying
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();
    
    // Set the viewport to be the entire window
    glViewport(0, 0, SizeViewX  , SizeViewY);

    // Set the correct perspective.
    gluPerspective(45,ratio,1,1000);



}
void GameView::moveCamera(void)
{
    if (!pause) 
    { 
    float tmp_k, tmp_h;
    float a= 2*M_PI*(x-ox)/SizeViewX;
    tmp_k=k+a;
    float b= 25*(oy-y)/(float)SizeViewY;
    tmp_h=h+b;

    if (tmp_h<1.5) tmp_h=1.5;
    if (tmp_h>25) tmp_h=25;

    if (mp.getY((camera.m_vPosition.x()+camera.m_vView.x()+sin(v)*tmp_h*sin(tmp_k))/2,(camera.m_vPosition.z()+camera.m_vView.z()+sin(v)*tmp_h*cos(tmp_k))/2)+1< 
        (camera.m_vPosition.y()+ball.vet_posizione.y()+cos(v)*tmp_h)/2)
        
        {
            hl=h;
            kl=k;
            k=tmp_k;
            h=tmp_h;
        }
    else 
        {
            h=hl; k=kl;
        }
    }
}

int GameView::Draw(void)

{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
    glMatrixMode(GL_PROJECTION);    
    glLoadIdentity();
    glOrtho(-100,100,-100,100,-100,100);

    // Inizializzazione della Modelview Matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    //==============================camera draw=============================
    glMatrixMode(GL_PROJECTION);    
    glLoadIdentity();                       
    gluPerspective(55.0f,(GLfloat)SizeViewX/(GLfloat)SizeViewY, .5f, 150.0f);

    camera.Draw();
    //======================================================================

    //========================mappa draw====================================      
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    mp.Draw(optionGraphics);
    //======================================================================= 

    //========================enemy draw=====================================
    for (int i=0;i<MAXENEMY;i++)
    {
      if( mp.Enemys[i].first.X != -1) enemy[i].Draw(optionGraphics+optionEnemy);
    }
    //======================================================================= 

    //==========================palla draw===================================
    ball.Draw(optionGraphics);
    //=======================================================================

    if (!pause) 
    
    {
        console.glPrintf(SizeViewX/2,5,1,12,false,"life:%d - Time:%d -Fps:%d",num_vite,conto_alla_rovescia,fps );
        console.DrawBox(0,0,SizeViewX,20,false);
    }
    else 
    {
        console.setSize(SizeViewX,SizeViewY);

        console.menu(menu,item);
        console.glPrintf(SizeViewX/2,5,1,12,false,"life:%d -Fps:%d",num_vite, fps,conto_alla_rovescia );
        console.DrawBox(0,0,SizeViewX,20,false);
    }

    glFlush();

    glutSwapBuffers();
    return 0;
}


void GameView::moveBall(int type)
{ 

    Point3f comp; 
    float j,n,a,b,vx,vz;
    float ca;

    switch(type)
    {
    case ROLLCONTROL:


    j=(x-ox);
    n=(y-oy);
    if (j>sns)  j=sns;
    if (j<-sns) j=-sns;
    if (n>sns) n=sns;
    if (n<-sns) n=-sns;
         a=(j)/(float) SizeViewX;
        b=(n)/(float) SizeViewY;
        vx=(-a*sin(k)+b*cos(k))*sns*1000*dt;
        vz=(b*sin(k)+a*cos(k))*sns*1000*dt;
    if (camerafollowball) {
        ca=-2*M_PI*(x-ox)/SizeViewX;
        kl=kl+ca;}

    comp[2]=vx;
        comp[0]=vz;
        

        
        comp[1]=0;
    
    

    break;
    case C_UP:  
            vx=(0.0*sin(k)-0.1*cos(k))*sns/dt;
                        vz=(-0.1*sin(k)+0.0*cos(k))*sns/dt;
                        comp[2]=vx;
                        comp[0]=vz;
                        comp[1]=0;
        break;
        
    case C_DOWN:
            vx=(0.0*sin(k)+0.1*cos(k))*sns/dt;
                        vz=(0.1*sin(k)+0.0*cos(k))*sns/dt;
                        comp[2]=vx;
                        comp[0]=vz;
                        comp[1]=0;
        break;

    case C_RIGHT:
            vx=(-0.1*sin(k)+0*cos(k))*sns/dt;
                        vz=(0*sin(k)+0.1*cos(k))*sns/dt;
                        comp[2]=vx;
                        comp[0]=vz;
                        comp[1]=0;
            
    if (camerafollowball) {
        ca=-2*M_PI*0.1;
        kl=kl+ca;}

        break;


    case C_LEFT:
            vx=(0.1*sin(k)+0*cos(k))*sns/dt;
                        vz=(0*sin(k)-0.1*cos(k))*sns/dt;
                        comp[2]=vx;
                        comp[0]=vz;
                        comp[1]=0;
    if (camerafollowball) {
        ca= 2*M_PI*0.1;
        kl=kl+ca;}

        break;


        break;



    case LUKECONTROL:
        int old_y=SizeViewY/2;
        int old_x=SizeViewX/2;    
        float c = (sqrt( (x-old_x)*(x-old_x)+(y-old_y)*(y-old_y) ) );
     
    
        if (c > 80.0)    // e' il raggio del cerchi intorno alla pallina che modifica il vett velocita oltre 80
         {               // pixel rimane 80 in norma

          float d=c/80.0;
         
          comp[2]= ((old_x-x)/d)*sin(k)+((y-old_y)/d)*cos(k); 
          comp[0]= ((y-old_y)/d)*sin(k)+((x-old_x)/d)*cos(k);
          comp[1]=  0;   
      
         }
      
        else

         {   
            comp[2]= (old_x-x)*sin(k)+(y-old_y)*cos(k);
            comp[0]= (y-old_y)*sin(k)+(x-old_x)*cos(k);
            comp[1]=  0;          //per piano inclinato
         }
        break;
    
    
    }

    ball.vet_compon_controllo = comp;

}

void GameView::Update (void)
{ 

    int status_goal;
    frame++;
    time=glutGet(GLUT_ELAPSED_TIME);

    if (time -timebase > 1000) 

    {       
       if (!pause)

       {
            //============conto alla rovescia=========================================
            conto_alla_rovescia = (conto_alla_rovescia -((time -timebase)/1000 ) );
            //========================================================================
        }
        fps =(( frame*1000.0)/(time-timebase));
        timebase = time;        
        frame = 0;
    }
    if (fps==0) fps=1;
    dt=1.0/fps;

    if (!pause)
    {
    ball.Update(&mp,dt);
    //==================================gestione morte e partita============================
     int x=0;
     int z=0;
     x = floor(ball.vet_posizione.x());
     z = floor(ball.vet_posizione.z());
    
     if (!((x<0)||(z<0)||(z>=MAXMAP)||(x>=MAXMAP)))  status_goal=mp.Map[x][z].goal;
     else status_goal=0;
     if(status_goal == 0) 
         {
          if(conto_alla_rovescia==0) 

           {

                pause=true;
                menu=MENU_TIMEOUT;
           }

          if (ball.palla_viva == false)

            {
                pause=true;
                menu=MENU_DEAD;

            }
        }
    else

        {   
            menu=MENU_GOAL;
            pause=true;
        } 
    //========================================================================================

    //===============================gestione enemy===========================================
    for (int i=0;i<MAXENEMY;i++)
        {
        if( mp.Enemys[i].first.X != -1)enemy[i].Intelligenza(&ball,&mp,enemy);
        if( mp.Enemys[i].first.X != -1)enemy[i].Update(&mp,dt);
    
    
        }
    //========================================================================================
    }
    

}

void GameView::setMouse(int cx, int cy)
{
    ox=x;
    oy=y;
    x=cx;
    y=cy;
}

void GameView::TargetCamera(void)
{

    if (pause) {  kl=kl+dt/10;  } 
        
    if  (!mp.intersect((camera.m_vPosition.x()+camera.m_vView.x()+sin(v)*h*sin(k))/2,
                          (camera.m_vPosition.y()+camera.m_vView.y()+cos(v)*h)/2,
                          (camera.m_vPosition.z()+camera.m_vView.z()+sin(v)*h*cos(k))/2,
                          (camera.m_vView.x()+ball.vet_posizione.x())/2,
                         (camera.m_vView.y()+ball.vet_posizione.y())/2,
                          (camera.m_vView.z()+ball.vet_posizione.z())/2))
        {                       
        v=v-0.1;
        if (v<0.1){ 
        v=0.1; }
        h=h-0.1;
        if (h<1.5) h=1.5;

        }
        else { 
    

        if  (mp.intersect((camera.m_vPosition.x()+camera.m_vView.x()+sin(vl)*h*sin(k))/2,
                         (camera.m_vPosition.y()+camera.m_vView.y()+cos(vl)*h)/2,
                         (camera.m_vPosition.z()+camera.m_vView.z()+sin(vl)*h*cos(k))/2,
                         (camera.m_vView.x()+ball.vet_posizione.x())/2,
                         (camera.m_vView.y()+ball.vet_posizione.y())/2,
                         (camera.m_vView.z()+ball.vet_posizione.z())/2))
                         v=(v/(dt)+vl)/(1/dt+1);
        
        if  (mp.intersect((camera.m_vPosition.x()+camera.m_vView.x()+sin(v)*(hl)*sin(k))/2,
                         (camera.m_vPosition.y()+camera.m_vView.y()+cos(v)*(hl))/2,
                         (camera.m_vPosition.z()+camera.m_vView.z()+sin(v)*(hl)*cos(k))/2,
                         (camera.m_vView.x()+ball.vet_posizione.x())/2,
                         (camera.m_vView.y()+ball.vet_posizione.y())/2,
                         (camera.m_vView.z()+ball.vet_posizione.z())/2))
                         h=(h/(dt)+hl)/(1/dt+1);

        if  (mp.intersect((camera.m_vPosition.x()+camera.m_vView.x()+sin(v)*(h)*sin(kl))/2,
                         (camera.m_vPosition.y()+camera.m_vView.y()+cos(v)*(h))/2,
                         (camera.m_vPosition.z()+camera.m_vView.z()+sin(v)*(h)*cos(kl))/2,
                         (camera.m_vView.x()+ball.vet_posizione.x())/2,
                         (camera.m_vView.y()+ball.vet_posizione.y())/2,
                         (camera.m_vView.z()+ball.vet_posizione.z())/2))
                         k=(k/(dt)+kl)/(1/dt+1);



        } 
   if (camera.m_vPosition.y()<mp.getY(camera.m_vPosition.x(),camera.m_vPosition.z())+1)
   {if (h>=2.5) h=h-1;}
    camera.PositionCamera((camera.m_vPosition.x()+camera.m_vView.x()+sin(v)*h*sin(k))/2,(camera.m_vPosition.y()+camera.m_vView.y()+cos(v)*h)/2,(camera.m_vPosition.z()+camera.m_vView.z()+sin(v)*h*cos(k))/2,
   (camera.m_vView.x()+ball.vet_posizione.x())/2,(camera.m_vView.y()+ball.vet_posizione.y())/2,(camera.m_vView.z()+ball.vet_posizione.z())/2,   0, 1, 0);
    

}


void GameView::move(void)

{
    if (!pause) 
    {

     if (b_left) moveBall(scontrol);
     if (b_right) moveCamera();
    
    }

}

void GameView::Pause(void)
{
    pause=!pause;
    menu=MENU_PAUSE;
}