#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>


#include "serverobject.h"
#include "servergame.h"
#include "serverdata.h"
#include "mainplayerthread.h"
#include "sizes.h"
#include "scorevals.h"
#include "sounddefs.h"
#include "matrix.h"


ServerObject::ServerObject(struct Point Pos, struct Point Vel,
                           struct Point Rot, int Type, float Size,
                           float Mass, int playernum)
{
  int i;

  memcpy(&Position, &Pos, sizeof(struct Point));
  memcpy(&Velocity, &Vel, sizeof(struct Point));
  memcpy(&Rotation, &Rot, sizeof(struct Point));

  PlayerNum=playernum;
  ObjectType=Type;
  ObjectSize=Size;
  ObjectMass=Mass;

  if (Type==SHIP_TYPE) {
    AliveTime=-1;
  } else if (Type==SHOT_TYPE) {
    AliveTime=ShotAliveTime;
  } else if (Type==EXPLOSION_TYPE) {
    AliveTime=20;
  } else if (Type==BIG_EXPLOSION_TYPE) {
    AliveTime=65;
  } else if (Type==ASTEROID_TYPE) {
    AliveTime=-1;
    NumAsteroids++;
    TotalAsteroidSize+=ObjectSize;
  } else if (Type==SHIELD_POWERUP_TYPE || Type==ARMOR_POWERUP_TYPE ||
             Type==NUKE_POWERUP_TYPE || Type==HYPERWARP_POWERUP_TYPE) {
    AliveTime=PowerupAliveTime;
  } else if (Type==NUKE_TYPE) {
    AliveTime=NukeAliveTime;
  } else if (Type==NUKE_EXPLOSION_TYPE) {
    AliveTime=NukeExplosionAliveTime;
    for (i=0; i<MAX_PLAYERS; i++) {
      PlayersHit[i]=0;
    }
  }

  InitMatrix(RotationMatrix);
}


ServerObject::~ServerObject()
{
  int i;
  int type;

  if (ObjectType==ASTEROID_TYPE) {
    NumAsteroids--;
    TotalAsteroidSize-=ObjectSize;
  }

  if (ObjectType==BIG_EXPLOSION_TYPE && rand()%1024 < PrizeOdds || ObjectType==NUKE_TYPE) {
    for (i=0; i<MAX_OBJECTS; i++) {
      if (!ServerObjects[i]) {
        if (ObjectType==BIG_EXPLOSION_TYPE) {
          type=rand()%4+SHIELD_POWERUP_TYPE;
          ServerObjects[i]=new ServerObject(Position, Velocity, Rotation, type, 0.1, 0.0);
          break;
        } else if (ObjectType==NUKE_TYPE) {
          Velocity.x=0.0;
          Velocity.y=0.0;
          Velocity.z=0.0;
          ServerObjects[i]=new ServerObject(Position, Velocity, Rotation,
                                            NUKE_EXPLOSION_TYPE, 0.1, 0.0, PlayerNum);
          AddSoundAll(&Position, NukeExplodeSound);
          break;
        }
      }
    }
  }
}


void ServerObject::UpdatePosition()
{
  Position.x+=Velocity.x;
  Position.y+=Velocity.y;
  Position.z+=Velocity.z;

  if (Position.x > WorldWidth) {
    Position.x-=WorldWidth*2.0;
  }
  if (Position.y > WorldWidth) {
    Position.y-=WorldWidth*2.0;
  }
  if (Position.z > WorldWidth) {
    Position.z-=WorldWidth*2.0;
  }
  if (Position.x < -WorldWidth) {
    Position.x+=WorldWidth*2.0;
  }
  if (Position.y < -WorldWidth) {
    Position.y+=WorldWidth*2.0;
  }
  if (Position.z < -WorldWidth) {
    Position.z+=WorldWidth*2.0;
  }
}


void ServerObject::UpdateRotation()
{
  xRotateMatrix(Rotation.x, RotationMatrix, 2);
  yRotateMatrix(Rotation.y, RotationMatrix, 2);
  zRotateMatrix(Rotation.z, RotationMatrix, 2);
}
