namespace BP
{
	namespace Weapon
	{
		class Nuke : ScriptWeapon
		{   
			float m_spinRotVel;
			float m_spinAngle;
			bool m_bReleased;
			//------------------------------------------------------------------------------------------------------------------------
			Nuke(kWeapon @actor)
			{
				id = kWpn_Nuke;
				super(actor);
				
				m_spinRotVel = 0;
				m_spinAngle = 0;
				m_bReleased = false;
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnSerialize(kDict& out dict)
			{
				SERIALIZE(m_spinRotVel);
				SERIALIZE(m_spinAngle);
				SERIALIZE(m_bReleased);
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnDeserialize(kDict& in dict)
			{
				DESERIALIZE_FLOAT(m_spinRotVel);
				DESERIALIZE_FLOAT(m_spinAngle);
				DESERIALIZE_BOOL(m_bReleased);
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnBeginFire(void) override
			{
				ScriptWeapon::OnBeginFire();
				self.PlayLoopingSound("sounds/shaders/Nuke Windup.ksnd");
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnEndFire(void) override
			{
				ScriptWeapon::OnEndFire();
				self.StopLoopingSounds();
				self.AnimTrackComponent().Flags() |= ANF_CYCLECOMPLETED;
				
				if(self.AnimTrackComponent().PlayTime() >= 2.0f)
				{
					m_spinRotVel = 2;
					self.RenderMeshComponent().SetRotationOffset(1, Math::Deg2Rad(m_spinAngle), 0, 1, 0);
					self.RenderMeshComponent().SetRotationOffset(12, Math::Deg2Rad(-m_spinAngle*2), 0, 1, 0);
					return;
				}
				
				m_bReleased = true;
				
				// note that this function is called before the engine sets the 'discharge'
				// animation on the weapon. flagging nointerrupt will prevent that from happening,
				// allowing us to set this animation
				self.AnimTrackComponent().Blend(ANIM_WPN_IDLE, 4, 16, ANF_NOINTERRUPT);
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnFire(void) override
			{
				ScriptWeapon::OnFire();
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnTick(void) override
			{
				ScriptWeapon::OnTick();
				if(m_bReleased)
				{
					// clear the flag so we can immediately start using the weapon again
					self.AnimTrackComponent().Flags() |= ANF_CYCLECOMPLETED;
					self.AnimTrackComponent().Flags() &= ~ANF_NOINTERRUPT;
					m_bReleased = false;
				}
				
				int animID = self.AnimTrackComponent().PlayingID();
				
				if(animID == ANIM_WPN_CHARGE)
				{
					m_spinRotVel = Math::IncMax(m_spinRotVel, 0.025f, 8);
				}
				else if(animID == ANIM_WPN_IDLE || animID == ANIM_WPN_RUN)
				{
					m_spinRotVel = Math::IncMax(m_spinRotVel, Math::Deg2Rad(0.375f) * GAME_FRAME_UNIT, 2);
				}
				else
				{
					return;
				}
				
				self.RenderMeshComponent().SetRotationOffset(1, Math::Deg2Rad(m_spinAngle), 0, 1, 0);
				self.RenderMeshComponent().SetRotationOffset(12, Math::Deg2Rad(-m_spinAngle*2), 0, 1, 0);
				
				m_spinAngle += m_spinRotVel;
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnLower(void) override
			{
				ScriptWeapon::OnLower();
				m_spinAngle = 0;
				self.RenderMeshComponent().SetRotationOffset(1, Math::Deg2Rad(0), 0, 1, 0);
				self.RenderMeshComponent().SetRotationOffset(12, Math::Deg2Rad(0), 0, 1, 0);
			}
			//------------------------------------------------------------------------------------------------------------------------
			void OnRaise(void) override
			{
				ScriptWeapon::OnRaise();
				m_spinRotVel = 0;
			}
			//------------------------------------------------------------------------------------------------------------------------
		};
	}
}
