/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team

This file is part of OpenMoHAA source code.

OpenMoHAA source code 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.

OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/

// portal.cpp: Portals - surfaces that are mirrors or cameras

#include "portal.h"
#include "game.h"

/*QUAKED portal_surface (1 0 1) (-8 -8 -8) (8 8 8)
The portal surface nearest this entity will show a view from the targeted portal_camera, or a mirror view if untargeted.
*/
   
Event EV_Portal_LocateCamera
	( 
	"locatecamera",
	EV_DEFAULT,
   NULL,
   NULL,
   "Locates the camera position.",
   EV_NORMAL
	);

CLASS_DECLARATION( Entity, PortalSurface, "portal_surface" )
	{
      { &EV_Portal_LocateCamera,     &PortalSurface::LocateCamera },
		{ NULL, NULL }
	};

void PortalSurface::LocateCamera
   (
   Event *ev 
   )

   {
	Entity   *owner;
	Entity   *target;
   Vector   dir;

	owner = ( Entity * )G_FindTarget( NULL, Target() );

   if ( !owner )
      {
      // No target, just a mirror
      VectorCopy( edict->s.origin, edict->s.origin2 );
      return;
      }

	// skinNum holds the rotate offset
	edict->s.skinNum = owner->edict->s.skinNum;

	VectorCopy( owner->origin, edict->s.origin2 );

	// see if the portal_camera has a target
	target = ( Entity * )G_FindTarget( NULL, owner->Target() );

	if ( target )
      {
		dir = target->origin - owner->origin;
		dir.normalize();
      setAngles( dir.toAngles() );
	   } 
   else
      {
      setAngles( owner->angles );
		dir = owner->orientation[ 0 ];
	   }
   }

PortalSurface::PortalSurface
   (
   )

   {
   if ( LoadingSavegame )
      {
      // Archive function will setup all necessary data
      return;
      }

   VectorClear( edict->r.mins );
   VectorClear( edict->r.maxs );

	gi.linkentity( edict );

	edict->r.svFlags = SVF_PORTAL | SVF_SENDPVS;
	edict->s.eType = ET_PORTAL;

   PostEvent( EV_Portal_LocateCamera, EV_POSTSPAWN );
   }


/*QUAKED portal_camera (1 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate
The target for a portal_surface.  You can set either angles or target another entity to determine the direction of view.
"roll" an angle modifier to orient the camera around the target vector;
*/
   
Event EV_Portal_Roll
	( 
	"roll",
	EV_DEFAULT,
   "f",
   "roll",
   "Sets the portal camera's roll.",
   EV_NORMAL
	);

CLASS_DECLARATION( Entity, PortalCamera, "portal_camera" )
	{
      { &EV_Portal_Roll,         &PortalCamera::Roll },
		{ NULL, NULL }
	};

void PortalCamera::Roll   
   (
   Event *ev
   )

   {
   float roll = ev->GetFloat( 1 );

   // skinNum holds the roll
   edict->s.skinNum = roll/360.0f * 256;
   }

PortalCamera::PortalCamera
   (
   )

   {
   if ( LoadingSavegame )
      {
      // Archive function will setup all necessary data
      return;
      }

   VectorClear( edict->r.mins );
   VectorClear( edict->r.maxs );

   // No roll on the camera by default
   edict->s.skinNum = 0;
   
   gi.linkentity( edict );
   }
