// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#ifndef LINUX
#pragma warning(disable: 4267 4244 4018 4996 4355)

#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <tchar.h>

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <string>
#include <set>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <math.h>
#include <sstream>
#include <io.h>
#include <queue>

#undef _CRT_SECURE_NO_DEPRECATE
#define NOT_USE_CRY_STRING
#include "Cry_Math.h"

static inline bool CryAssert(const char *_pszCondition,const char *_pszFile,unsigned int _uiLine, bool *_pbDontCare)
{
	_asm int 3;
	return false;
}

static inline void CryAssertTrace(const char *_pszFormat,...)
{
}

// TODO: reference additional headers your program requires here


//typedef std::string string;
typedef unsigned int uint32;
typedef int int32;
typedef unsigned short uint16;
typedef unsigned __int64 uint64;
typedef unsigned char uint8;

struct SVec3
{
	float x,y,z;
	SVec3(){}
	explicit SVec3(int a):x(float(a)),y(float(a)),z(float(a)){}
	SVec3(float _x,float _y,float _z):x(_x),y(_y),z(_z){}
	float operator[](int v)const
	{
		return *(&x + v);
	}
	float& operator[](int v)
	{
		return *(&x + v);
	}

	SVec3 operator-(const SVec3& l)const
	{
		return SVec3(x-l.x,y-l.y,z-l.z);
	}

	SVec3 operator+(const SVec3& l)const
	{
		return SVec3(x+l.x,y+l.y,z+l.z);
	}

	SVec3 operator*(const float f)const
	{
		return SVec3(x*f,y*f,z*f);
	}

	SVec3 operator/(const float f)const
	{
		return SVec3(x/f,y/f,z/f);
	}

	float GetLength() const
	{
		return sqrtf(x*x + y*y + z*z);
	}

	float GetLength2D() const
	{
		return sqrtf(x*x + y*y);
	}

	float GetDistance(const SVec3& v)
	{
		return sqrtf( (v.x - x) * (v.x - x) + (v.y - y) * (v.y - y) + (v.z - z) * (v.z - z) );
	}

	SVec3& Normalize()
	{
		float len = GetLength();
		float inv = 1.0f/len;
		x *= inv;
		y *= inv;
		z *= inv;
		return *this;
	}

	SVec3 GetNormalized()
	{
		float len = GetLength();
		float inv = 1.0f/len;
		return SVec3(x*inv, y*inv, z*inv);
	}

	float Dot( const SVec3& v ) const
	{
		return x*v.x + y*v.y + z*v.z;
	}

	SVec3 Cross( const SVec3& v ) const
	{
		return SVec3( y*v.z  -  z*v.y,     z*v.x -    x*v.z,   x*v.y  -  y*v.x);
	}
};

static float GetYaw( const SVec3& v0, const SVec3& v1)
{
	SVec3 cross = v0.Cross(v1);
	float sign = (cross.z<0) ? -1.0f : 1.0f;
	return atan2f( sign*cross.GetLength(), v0.Dot(v1) );
}

const float MAX_VALUE = 10000.0f;

static inline string KeyToString(uint32 key)
{
	string s;
	char* p = (char*)&key;
	for (int i = 3; i >= 0; --i)
		s += isalnum(p[i]) ? p[i] : '#';
	return s;
}

static inline uint32 StringToKey(const string& s)
{
	if (s.length() > 4)
		return 0;
	uint32 key = 0;
	char* p = (char*)&key;
	for (size_t i = 0; i < s.length(); ++i)
		p[i] = s[s.length()-i-1];
	return key;
}

#endif

