#include <pr.h>
#include <mem.h>


/*

Unfinished source code for different input models.

Input Device Module:

 Revision History:
 August 11, 1996: Created

*/


PR_DWORD PR_InputDevice;             /* Input device */
PR_DWORD PR_InputModel;              /* Movement type */
PR_ENTITY *PR_InputEntity;           /* Entity attached to input */
PR_DWORD   PR_InputSegment;          /* Segment attached to input */
PR_CAMERA *PR_InputCamera;           /* Camera attached to input */

PR_REAL currentspeed = 0;
PR_REAL rollspeed = 0;
PR_REAL pitchspeed = 0;
PR_REAL yawspeed = 0;

PR_REAL TRANSLATE_SPEED    = 150;
PR_REAL MAX_TRANSLATE_SPEED= 1400;
PR_REAL TRANSLATE_DRAG     = 20;

PR_REAL PITCH_SPEED        = 0.6;
PR_REAL MAX_PITCH_SPEED    =   4;
PR_REAL PITCH_DRAG         = 0.2;

PR_REAL YAW_SPEED          = 1.0;
PR_REAL MAX_YAW_SPEED      =   6;
PR_REAL YAW_DRAG           = 0.3;

PR_REAL ROLL_SPEED         = 2.7;
PR_REAL MAX_ROLL_SPEED     =  30;
PR_REAL ROLL_DRAG          = 0.6;
PR_REAL cambase_roll = 0;          /* 0 or 180 depending on orientation */
PR_REAL oribase_roll = 0;          /* 0 or 180 depending on orientation */


void PR_ReadInput (void)
/* Reads input from the user, based on the movement model */
{
  switch (PR_InputModel)
    {
     case MODEL_WALKING:
       PR_ReadWalking ();
       break;
     case MODEL_FLYING:
       PR_ReadFlying ();
       break;
     case MODEL_INSPECT:
       PR_ReadInspect ();
       break;
     case MODEL_STEER:
       PR_ReadSteer ();
       break;
    }
}


void PR_SetInputCamera (PR_CAMERA *cam)
/* Sets the camera attached to the input device */
{
  PR_InputCamera = cam;
}


void PR_SetInputDevice (PR_DWORD devicetype)
/* Sets the input device used for controlling the objects */
{
  PR_InputDevice = devicetype;
}


void PR_SetInputEntity (PR_ENTITY *entity, PR_DWORD segnum)
/* Sets the entity and segment attached to the input device */
{
  PR_InputEntity = entity;

  if ((segnum >= 0) && (segnum < entity->shape->num_segments))
    PR_InputSegment = segnum;
  else
    PR_InputSegment = -1;
}


void PR_SetInputModel (PR_DWORD modeltype)
/* Sets the viewing model used */
{
  PR_InputModel = modeltype;

  if (modeltype == MODEL_FLYING)
    {
     TRANSLATE_SPEED    = 150;
     MAX_TRANSLATE_SPEED= 1400;
     TRANSLATE_DRAG     = 20;

     PITCH_SPEED        = 0.6;
     MAX_PITCH_SPEED    =   4;
     PITCH_DRAG         = 0.2;

     YAW_SPEED          = 1.0;
     MAX_YAW_SPEED      =   6;
     YAW_DRAG           = 0.3;

     ROLL_SPEED         = 2.7;
     MAX_ROLL_SPEED     =  30;
     ROLL_DRAG          = 0.6;
     cambase_roll = 0;          /* 0 or 180 depending on orientation */
     oribase_roll = 0;          /* 0 or 180 depending on orientation */
    }
  else if (modeltype == MODEL_WALKING)
    {
     TRANSLATE_SPEED    = 125;
     MAX_TRANSLATE_SPEED= 900;
     TRANSLATE_DRAG     = 10;

     PITCH_SPEED        = 0.6;
     MAX_PITCH_SPEED    =   4;
     PITCH_DRAG         = 10;

     YAW_SPEED          = 1.0;
     MAX_YAW_SPEED      =   6;
     YAW_DRAG           = 10;

     ROLL_SPEED         = 2.7;
     MAX_ROLL_SPEED     =  30;
     ROLL_DRAG          = 10;
     cambase_roll = 0;          /* 0 or 180 depending on orientation */
     oribase_roll = 0;          /* 0 or 180 depending on orientation */
    }
  else if (modeltype == MODEL_STEER)
    {
     TRANSLATE_SPEED    = 150;
     MAX_TRANSLATE_SPEED= 1500;
     TRANSLATE_DRAG     = 60;

     PITCH_SPEED        = 0.6;
     MAX_PITCH_SPEED    =   4;
     PITCH_DRAG         = 10;

     YAW_SPEED          = 0.3;
     MAX_YAW_SPEED      =   6;
     YAW_DRAG           = 0.5;

     ROLL_SPEED         = 2.7;
     MAX_ROLL_SPEED     =  30;
     ROLL_DRAG          = 10;
     cambase_roll = 0;          /* 0 or 180 depending on orientation */
     oribase_roll = 0;          /* 0 or 180 depending on orientation */
    }
}




void SmoothMove (PR_REAL *value, PR_REAL amount, PR_REAL max,
                 PR_REAL drag)
/* Adds one value to another, checks for a maximum value, and
   adds a drag factor if the amount is 0 */
{
  if (amount > 0)
    {
     *value += amount;
     if (*value > max)
       *value = max;
    }
  else if (amount < 0)
    {
     *value += amount;
     if (*value < -max)
       *value = -max;
    }
  else /* Slow down gradually */
    {
     if (*value > 0)
       {
        *value -= drag;
        if (*value < 0)
          *value = 0;
       }
     else if (*value < 0)
       {
        *value += drag;
        if (*value > 0)
          *value = 0;
       }
    }
}



void PR_ReadWalking (void)
{
  /* Keyboard input */
  if (PR_InputDevice == INPUT_KEYBOARD)
    {
     /* Pitch */
     if (kbdon[KEY_A])
        SmoothMove (&pitchspeed, PITCH_SPEED, MAX_PITCH_SPEED,
                                 PITCH_DRAG);
     else if (kbdon[KEY_Z])
        SmoothMove (&pitchspeed, -PITCH_SPEED, MAX_PITCH_SPEED,
                                 PITCH_DRAG);
     else /* Slow down gradually */
        SmoothMove (&pitchspeed, 0, MAX_PITCH_SPEED,
                                 PITCH_DRAG);

     /* Yaw */   
     if (kbdon[KEY_RIGHT])
       {
        SmoothMove (&yawspeed, YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
       }
     else if (kbdon[KEY_LEFT])
       {
        SmoothMove (&yawspeed, -YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
       }
     else /* Slow down gradually */
       {
        SmoothMove (&yawspeed, 0, MAX_YAW_SPEED,
                                 YAW_DRAG);
       }

     /* Thrust */
     if (kbdon[KEY_UP])
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_DOWN])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);
    }
  else
    {
     /* Pitch */
     pitchspeed = (mouse.my - 100)*(-0.16); /* Pitch */
     yawspeed = (mouse.mx - 160)*(0.20); /* Yaw */

     msetxy (160, 100);

     /* Thrust */
     if ((mouse.but == 2) || (kbdon[KEY_UP]))
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_DOWN])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);
    }


  /* Modify the camera rotation */
  if (PR_InputCamera != NULL)
    {
     if (yawspeed > 0) /* Yaw right */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y >= 360)
          PR_InputCamera->rotation.y -= 360;
       }
     if (yawspeed < 0) /* Yaw left */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y < 0)
          PR_InputCamera->rotation.y += 360;
       }


     PR_InputCamera->rotation.x += pitchspeed;
     if (PR_InputCamera->rotation.x > 89)
       PR_InputCamera->rotation.x = 89;
     if (PR_InputCamera->rotation.x < -89)
       PR_InputCamera->rotation.x = -89;
    }

  /* Modify the orientation rotation */
  if (PR_InputSegment > 0)
     PR_RotateSegment (PR_InputEntity, PR_InputSegment, 0, yawspeed, 0);
  else if (PR_InputEntity != NULL)
     PR_RotateEntity (PR_InputEntity, 0, yawspeed, 0);
}


void PR_ReadSteer (void)
{
  /* Keyboard input */
  if (PR_InputDevice == INPUT_KEYBOARD)
    {
     /* Yaw */   
     if (kbdon[KEY_RIGHT])
       {
        SmoothMove (&yawspeed, YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
       }
     else if (kbdon[KEY_LEFT])
       {
        SmoothMove (&yawspeed, -YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
       }
     else /* Slow down gradually */
       {
        SmoothMove (&yawspeed, 0, MAX_YAW_SPEED,
                                 YAW_DRAG);
       }

     /* Thrust */
     if (kbdon[KEY_UP])
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_DOWN])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);
    }
  else
    {
     /* Pitch */
     yawspeed = (mouse.mx - 160)*(0.20); /* Yaw */

     msetxy (160, 100);

     /* Thrust */
     if ((mouse.but == 2) || (kbdon[KEY_UP]))
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_DOWN])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);
    }


  /* Modify the camera rotation */
  if (PR_InputCamera != NULL)
    {
     if (yawspeed > 0) /* Yaw right */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y >= 360)
          PR_InputCamera->rotation.y -= 360;
       }
     if (yawspeed < 0) /* Yaw left */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y < 0)
          PR_InputCamera->rotation.y += 360;
       }

     PR_InputCamera->tilt_angle = cambase_roll + rollspeed;
    }

  /* Modify the orientation rotation */
  if (PR_InputSegment > 0)
     PR_RotateSegment (PR_InputEntity, PR_InputSegment, 0, yawspeed, 0);
  else if (PR_InputEntity != NULL)
     PR_RotateEntity (PR_InputEntity, 0, yawspeed, 0);
     

/*
  if (PR_InputOrientation != NULL)
    {
     if (yawspeed > 0) 
       {
        PR_InputOrientation->rot.y += yawspeed;
        if (PR_InputOrientation->rot.y >= 360)
          PR_InputOrientation->rot.y -= 360;
       }
     if (yawspeed < 0) 
       {
        PR_InputOrientation->rot.y += yawspeed;
        if (PR_InputOrientation->rot.y < 0)
          PR_InputOrientation->rot.y += 360;
       }
*/  

//     PR_InputOrientation->rot.z = oribase_roll + rollspeed;
}


void PR_ReadFlying (void)
{

  /* Keyboard input */
  if (PR_InputDevice == INPUT_KEYBOARD)
    {
     /* Pitch */
     if (kbdon[KEY_UP])
        SmoothMove (&pitchspeed, PITCH_SPEED, MAX_PITCH_SPEED,
                                 PITCH_DRAG);
     else if (kbdon[KEY_DOWN])
        SmoothMove (&pitchspeed, -PITCH_SPEED, MAX_PITCH_SPEED,
                                 PITCH_DRAG);
     else /* Slow down gradually */
        SmoothMove (&pitchspeed, 0, MAX_PITCH_SPEED,
                                 PITCH_DRAG);

     /* Yaw */   
     if (kbdon[KEY_RIGHT])
       {
        SmoothMove (&yawspeed, YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
        SmoothMove (&rollspeed, -ROLL_SPEED, MAX_ROLL_SPEED,
                                ROLL_DRAG);
       }
     else if (kbdon[KEY_LEFT])
       {
        SmoothMove (&yawspeed, -YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
        SmoothMove (&rollspeed, ROLL_SPEED, MAX_ROLL_SPEED,
                                ROLL_DRAG);
       }
     else /* Slow down gradually */
       {
        SmoothMove (&yawspeed, 0, MAX_YAW_SPEED,
                                 YAW_DRAG);
        SmoothMove (&rollspeed, 0, MAX_ROLL_SPEED,
                                 ROLL_DRAG);
       }

     /* Thrust */
     if (kbdon[KEY_A])
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_Z])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);

    }
  else /* Mouse control */
    {
     if (mouse.but == 0)
       {
        rollspeed = (mouse.mx - 160)*(0.2); /* Roll */
        yawspeed = (mouse.mx - 160)*(0.02); /* Yaw */
        pitchspeed = (mouse.my - 100)*(0.04); /* Pitch */
       }

     /* Thrust */
     if (kbdon[KEY_A])
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_Z])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);
    }


  /* Modify the camera rotation */
  if (PR_InputCamera != NULL)
    {
     if (yawspeed > 0) /* Yaw right */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y >= 360)
          PR_InputCamera->rotation.y -= 360;
       }
     if (yawspeed < 0) /* Yaw left */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y < 0)
          PR_InputCamera->rotation.y += 360;
       }
  
     if (pitchspeed < 0)   /* Pitch down */
       {
        if ((PR_InputCamera->rotation.x <= 270) && (PR_InputCamera->rotation.x >= 90))
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x < 90)
             cambase_roll += 180;
          }
        else if (PR_InputCamera->rotation.x > 270)
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x < 270)
             cambase_roll -= 180;
          }
        else
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x < 0)
             PR_InputCamera->rotation.x += 360;
          }
       }

     if (pitchspeed > 0) /* Pitch up */
       {
        if (PR_InputCamera->rotation.x <= 90)
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x > 90)
             cambase_roll += 180;
          }
        else if (PR_InputCamera->rotation.x <= 270)
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x > 270)
             cambase_roll -= 180;
          }
        else 
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x >= 360)
             PR_InputCamera->rotation.x -= 360;
          }
       }

     PR_InputCamera->tilt_angle = cambase_roll + rollspeed;
    }


  /* Modify the orientation rotation */
  if (PR_InputSegment > 0)
     PR_RotateSegment (PR_InputEntity, PR_InputSegment, pitchspeed, yawspeed, rollspeed);
  else if (PR_InputEntity != NULL)
     PR_RotateEntity (PR_InputEntity, pitchspeed, yawspeed, rollspeed);
}



void PR_ReadInspect (void)
{

  /* Keyboard input */
  if (PR_InputDevice == INPUT_KEYBOARD)
    {
     /* Pitch */
     if (kbdon[KEY_UP])
        SmoothMove (&pitchspeed, PITCH_SPEED, MAX_PITCH_SPEED,
                                 PITCH_DRAG);
     else if (kbdon[KEY_DOWN])
        SmoothMove (&pitchspeed, -PITCH_SPEED, MAX_PITCH_SPEED,
                                 PITCH_DRAG);
     else /* Slow down gradually */
        SmoothMove (&pitchspeed, 0, MAX_PITCH_SPEED,
                                 PITCH_DRAG);

     /* Yaw */   
     if (kbdon[KEY_RIGHT])
       {
        SmoothMove (&yawspeed, YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
        SmoothMove (&rollspeed, -ROLL_SPEED, MAX_ROLL_SPEED,
                                ROLL_DRAG);
       }
     else if (kbdon[KEY_LEFT])
       {
        SmoothMove (&yawspeed, -YAW_SPEED, MAX_YAW_SPEED,
                               YAW_DRAG);
        SmoothMove (&rollspeed, ROLL_SPEED, MAX_ROLL_SPEED,
                                ROLL_DRAG);
       }
     else /* Slow down gradually */
       {
        SmoothMove (&yawspeed, 0, MAX_YAW_SPEED,
                                 YAW_DRAG);
        SmoothMove (&rollspeed, 0, MAX_ROLL_SPEED,
                                 ROLL_DRAG);
       }

     /* Thrust */
     if (kbdon[KEY_A])
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_Z])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);

    }
  else /* Mouse control */
    {
     if (mouse.but == 0)
       {
        yawspeed = (mouse.mx - 160)*(0.2); /* Yaw */
        pitchspeed = (mouse.my - 100)*(0.2); /* Pitch */
       }

     /* Thrust */
     if (kbdon[KEY_A])
        SmoothMove (&currentspeed, TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                                   TRANSLATE_DRAG);
     else if (kbdon[KEY_Z])
        SmoothMove (&currentspeed, -TRANSLATE_SPEED, MAX_TRANSLATE_SPEED,
                               TRANSLATE_DRAG);
     else /* Slow down gradually */
        SmoothMove (&currentspeed, 0, MAX_TRANSLATE_SPEED,
                                  TRANSLATE_DRAG);
    }


  /* Modify the camera rotation */
  if (PR_InputCamera != NULL)
    {
     if (yawspeed > 0) /* Yaw right */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y >= 360)
          PR_InputCamera->rotation.y -= 360;
       }
     if (yawspeed < 0) /* Yaw left */
       {
        PR_InputCamera->rotation.y += yawspeed;
        if (PR_InputCamera->rotation.y < 0)
          PR_InputCamera->rotation.y += 360;
       }
  
     if (pitchspeed < 0)   /* Pitch down */
       {
        if ((PR_InputCamera->rotation.x <= 270) && (PR_InputCamera->rotation.x >= 90))
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x < 90)
             cambase_roll += 180;
          }
        else if (PR_InputCamera->rotation.x > 270)
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x < 270)
             cambase_roll -= 180;
          }
        else
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x < 0)
             PR_InputCamera->rotation.x += 360;
          }
       }

     if (pitchspeed > 0) /* Pitch up */
       {
        if (PR_InputCamera->rotation.x <= 90)
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x > 90)
             cambase_roll += 180;
          }
        else if (PR_InputCamera->rotation.x <= 270)
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x > 270)
             cambase_roll -= 180;
          }
        else 
          {
           PR_InputCamera->rotation.x += pitchspeed;
           if (PR_InputCamera->rotation.x >= 360)
             PR_InputCamera->rotation.x -= 360;
          }
       }

     PR_InputCamera->tilt_angle = cambase_roll;
    }


  /* Modify the orientation rotation */
  if (PR_InputSegment > 0)
     PR_RotateSegment (PR_InputEntity, PR_InputSegment, pitchspeed, yawspeed, rollspeed);
  else if (PR_InputEntity != NULL)
     PR_RotateEntity (PR_InputEntity, pitchspeed, yawspeed, rollspeed);
}


