--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| 	Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]


AddCSLuaFile()

local matBone = Material( "widgets/bone.png", "smooth" )
local matBoneSmall = Material( "widgets/bone_small.png", "smooth" )

local widget_bone = {
	Base = "widget_base",
	a = 255,

	GetParentPos = function( self )

		local p = self:GetParent()
		if ( !IsValid( p ) ) then return end

		local bp = p:GetBoneParent( self:GetParentAttachment() )
		if ( bp <= 0 ) then return end

		return p:GetBonePosition( bp )

	end,

	OverlayRender = function( self )

		local pp = self:GetParentPos()
		if ( !pp ) then return end

		--local fwd = self:GetAngles():Forward()
		local len = self:GetSize() / 2
		local w = len * 0.2

		if ( len > 10 ) then
			render.SetMaterial( matBone )
		else
			render.SetMaterial( matBoneSmall )
		end

		local c = Color( 255, 255, 255, 255 )

		if ( self:IsHovered() ) then
			self.a = math.Approach( self.a, 255, FrameTime() * 255 * 10 )
		elseif ( self:SomethingHovered() ) then
			self.a = math.Approach( self.a, 20, FrameTime() * 255 * 10 )
		else
			self.a = math.Approach( self.a, 255, FrameTime() * 255 * 10 )
		end

		cam.IgnoreZ( true )
			render.DrawBeam( self:GetPos(), pp, w, 0, 1, Color( c.r, c.g, c.b, self.a * 0.5 ) )
		cam.IgnoreZ( false )

		render.DrawBeam( self:GetPos(), pp, w, 0, 1, Color( c.r, c.g, c.b, self.a ) )

	end,

	TestCollision = function( self, startpos, delta, isbox, extents )

		if ( isbox ) then return end
		if ( !widgets.Tracing ) then return end

		local pp = self:GetParentPos()
		if ( !pp ) then return end

		local fwd = ( pp - self:GetPos() ):GetNormal()
		local ang = fwd:Angle()
		local len = self:GetSize() / 2
		local w = len * 0.2

		local mins = Vector( 0, w * -0.5, w * -0.5 )
		local maxs = Vector( len, w * 0.5, w * 0.5 )

		local hit, norm, fraction = util.IntersectRayWithOBB( startpos, delta, self:GetPos(), ang, mins, maxs )
		if ( !hit ) then return end

		--debugoverlay.BoxAngles( self:GetPos(), mins, maxs, ang, 0.1, Color( 0, 255, 0, 64 ) )

		return {
			HitPos		= hit,
			Fraction	= fraction * self:GetPriority()
		}

	end,

	Think = function( self )

		if ( !SERVER ) then return end
		if ( !IsValid( self:GetParent() ) ) then return end

		--
		-- Because the bone length changes (with the manipulator)
		-- we need to update the bones pretty regularly
		--

		local size = self:GetParent():BoneLength( self:GetParentAttachment() ) * 2
		size = math.ceil( size )

		self:SetSize( size )

	end,

	CalcAbsolutePosition = function( self, v, a )

		local ent = self:GetParent()
		if ( !IsValid( ent ) ) then return end

		local bone = self:GetParentAttachment()
		if ( bone <= 0 ) then return end

		return ent:GetBonePosition( bone )

	end
}

scripted_ents.Register( widget_bone, "widget_bone" )

DEFINE_BASECLASS( "widget_base" )

function ENT:SetupDataTables()

	self:NetworkVar( "Entity", 0, "Target" )

	self.BaseClass.SetupDataTables( self )

end

--
-- Set our dimensions etc
--
function ENT:Initialize()

	self.BaseClass.Initialize( self )

	self:SetCollisionBounds( Vector( -1, -1, -1 ), Vector( 1, 1, 1 ) )
	self:SetSolid( SOLID_NONE )

end

function ENT:Setup( ent )

	self:SetTarget( ent )
	self:SetParent( ent )
	self:SetLocalPos( vector_origin )

	for k = 0, ent:GetBoneCount() - 1 do

		if ( ent:GetBoneParent( k ) <= 0 ) then continue end
		if ( !ent:BoneHasFlag( k, BONE_USED_BY_VERTEX_LOD0 ) ) then continue end

		local btn = ents.Create( "widget_bone" )
		btn:FollowBone( ent, k )
		btn:SetLocalPos( vector_origin )
		btn:SetLocalAngles( angle_zero )
		btn:Spawn()
		btn:SetSize( ent:BoneLength( k ) * 2 )

		btn.OnClick = function( x, ply )
			self:OnBoneClick( k, ply )
		end

		self:DeleteOnRemove( btn )

	end

end

function ENT:OnBoneClick( boneid, ply )
end

function ENT:OverlayRender()
end
