/*
	Lan Wars.
	Copyright (c) 2009, Darragh Coy.
	All rights reserved.
	Original work(s), source code & author(s) details available at: http://www.darraghcoy.com

	Redistribution and use in source and binary forms, with or without modification, are permitted 
	provided that the following conditions are met:

		* 	Redistributions of source code must retain the above copyright notice, this list of 
			conditions and the following disclaimer.
		* 	Redistributions in binary form must reproduce the above copyright notice, this list of 
			conditions and the following disclaimer in the documentation.
		* 	Neither the name of the author nor the names of contributors may be used to endorse or 
			promote products derived from this software without specific prior written permission.
		* 	The use of any third party libraries, modules or data files provided with the source 
			form of the program must follow and respect the individual licensing terms of these 
			components. You do not have permission to modify or circumvent the licensing terms for 
			provided third party components unless the third party licenses specifically allow this. 
			If you do not agree to the terms of provided third party components then you do not have 
			permission to use them in your derived work(s).
		* 	The terms of this license do not apply to separate (but related) distributions if supplied 
			by the author(s), only to the contents of this source distribution, derived works, and the 
			binaries produced by either modified or unmodified versions of the source code. The terms 
			of this license do not also apply to any third party libraries or components provided with 
			the source distribution. Such third party elements are licensed under their own separate 
			agreements.

	THIS SOFTWARE IS PROVIDED BY DARRAGH COY ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
	ARE DISCLAIMED. IN NO EVENT SHALL DARRAGH COY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
	OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef GAME_DOOM_PP_SEG_H
#define GAME_DOOM_PP_SEG_H

//=====================================================================================================================
//=====================================================================================================================

namespace Game
{
	//=================================================================================================================
	//=================================================================================================================
	
	struct DoomGLSubsectorV2;

	//=================================================================================================================
	/// @brief		This is a preprocessed segment for doom. Because some of our vertices are in vanilla doom format
	///				and because some are in gldoom format (16.16 fixed point) this class pre-handles the conversions
	///				for extra speed. It also precalculates line directions and normals for later collision detection and
	///				raycasting, as well as providing some other useful information about the segment.
	//=================================================================================================================

	struct DoomPPSeg
	{
		/// This is the start point of the segment
		
		Vec2f m_start;
		
		/// This is the ending point of the segment
		
		Vec2f m_end;

		/// This is the normalised normal for the segment
		
		Vec2f m_normal;

		/// This is the normal in 3D

		Vec3f m_normal_3d;
		
		/// This is the normalised direction of the segment
		
		Vec2f m_direction;

		/// This is the direction in 3D

		Vec3f m_direction_3d;
		
		/// This is the length of the segment
		
		float m_length;
		
		/// This is the negative value of the start point dotted with the normal: used for determining which side of the plane a point is on
		
		float m_minus_n_dot_p;
		
		/// This is the negative value of the start point dotted with the direction: used for determining how far along the line a point is at
		
		float m_minus_d_dot_p;
		
		/// This enum represents the type of segment this is, and correspondingly what collision checks we should perform against it
		
		enum SegType
		{
			/// No collisions are performed with this segment.
			
			SEG_TYPE_NO_WALL = 0 ,
			
			/// This segment is a solid wall. We do not have to worry about upper and lower walls
			
			SEG_TYPE_FULL_WALL  = 1 , 
			
			/// This segment has a floor wall but no ceiling wall. We may collide with the lower wall
			
			SEG_TYPE_LOWER_WALL = 2 , 
			
			/// This segment only has a upper wall. We could potentially collide with it
			
			SEG_TYPE_UPPER_WALL = 4 , 
			
			/// This segment has a ceiling and a floor wall. We could collide with both.
			
			SEG_TYPE_LOWER_UPPER_WALL = 6			
		};
		
		/// This is the type of segment this is
		
		SegType m_type;
		
		/// This is the sector the segment belongs to:
		
		DoomSector * m_sector;
		
		/// This is the subsector the segment belongs to:
		
		DoomGLSubsectorV2 * m_subsector;
		
		/// This is the height of the floor for the sector the segment resides in
		
		float m_floor_height;
		
		/// This is the height of the ceiling for the sector the segment resides in
		
		float m_ceiling_height;
		
		/// If we have an upper wall then this is the height of the wall bottom
		
		float m_upper_height;
		
		/// If we have a lower wall then this is the height of the wall top
		
		float m_lower_height;
		
		//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
		/// This is the segment on the opposite side of this segment in the neighbouring subsector. 
		/// This will be null if there is no neighbouring subsegment.
		//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
		
		DoomPPSeg * m_opposite_seg;
		
		/// This is the linedef for the seg. This may be null if the seg is a 'miniseg' and was not created from a linedef
		
		DoomLinedef * m_linedef;
		
		/// This is the sidedef for the seg. This may be null if the seg is a 'miniseg' and was not created from a linedef
		
		DoomSidedef * m_sidedef;
	};
}

#endif
