local EYE_END = 11


if ( SERVER ) then

	/*---------------------------------------------------------
		Just select as the current object
		- Current settings will get applied
	---------------------------------------------------------*/
	function TOOL:LeftClick( trace )
	
		if (!trace.Entity:IsValid()) then return end
		
		self.SelectedEnt = trace.Entity
		self:GetWeapon():SetNetworkedEntity( 1, self.SelectedEnt )
		self:GetWeapon():CallOnClient( "UpdateFaceControlPanel", self.SelectedEnt:EntIndex() )
				
	end
	
	/*---------------------------------------------------------
		Alt fire sucks the facepose from the model's face and selects
	---------------------------------------------------------*/
	function TOOL:RightClick( trace )
	
		if (!trace.Entity:IsValid()) then return end
		
		self.SelectedEnt = trace.Entity
		self:GetWeapon():SetNetworkedEntity( 1, self.SelectedEnt )
		
		// This stops it applying the current sliders to the newly selected face.. 
		// it should probably be linked to the ping somehow.. but 1 second seems pretty safe
		self.FaceTimer = CurTime() + 1
		
		// Save bandwidth - this can be predicted
		if ( !SinglePlayer() ) then return end
		
		local ent = trace.Entity
		local FlexNum = ent:GetFlexNum()
		
		for i=0,FlexNum-1 do
			if (i > FlexNum - EYE_END) then
				self:GetOwner():ConCommand( "faceposer_flex"..i.." 0.0" )
			else
				self:GetOwner():ConCommand( "faceposer_flex"..i.." "..ent:GetFlexWeight(i) )
			end
		end
		
		self:GetOwner():ConCommand( "faceposer_scale "..ent:GetFlexScale() )	
		self:GetWeapon():CallOnClient( "UpdateFaceControlPanel", ent:EntIndex() )
		
	end
	
	/*---------------------------------------------------------
		Continually update the facepose
	---------------------------------------------------------*/
	function TOOL:Think()
	
		if (self.FaceTimer > CurTime() ) then return end
		
		if (self.SelectedEnt == nil) then return end
		if (!self.SelectedEnt:IsValid()) then return end
		
		local FlexNum = self.SelectedEnt:GetFlexNum()
		if (FlexNum == 0) then return end
		
		for i=0,FlexNum-1 do
			local num = self:GetClientInfo( "flex"..i )
			num = tonumber(num)
			if (num) then
			
				self.SelectedEnt:SetFlexWeight( i, num, false )
			end
		end
		
		local num = self:GetClientInfo( "scale" )
		self.SelectedEnt:SetFlexScale( tonumber(num) )
		
	end
	
	function CC_Face_Randomize( pl, command, arguments )
	
		local wep = pl:GetWeapon( "gmod_tool" )	
		local ent = wep:GetTable().Tool[ wep:GetTable():GetMode() ].SelectedEnt
	
		if (ent == nil) then return end
		if (!ent:IsValid()) then return end
		
		local FlexNum = ent:GetFlexNum()
		
		for i=0, FlexNum-EYE_END do
			local n, x = ent:GetFlexBounds( i )
			local num = mathx.Rand( n, x )
			pl:ConCommand( "faceposer_flex"..i.." "..num )
		end
	end
	
	concommand.Add( "faceposer_randomize", CC_Face_Randomize )
	
	TOOL.FaceTimer = 0
	
end

if ( CLIENT ) then

	for i=0,64 do
		TOOL.ClientConVar[ "flex"..i ] = "0.5"
	end
	
	TOOL.ClientConVar[ "scale" ] = "1.0"
	
	/*---------------------------------------------------------
		Alt fire sucks the facepose from the model's face
	---------------------------------------------------------*/
	function TOOL:RightClick( trace )
	
		if (!trace.Entity:IsValid()) then return end
		
		local ent = trace.Entity
		local FlexNum = ent:GetFlexNum()
		
		for i=0,FlexNum-1 do
			if (i > FlexNum - EYE_END) then
				self:GetOwner():ConCommand( "faceposer_flex"..i.." 0.0" )
			else
				self:GetOwner():ConCommand( "faceposer_flex"..i.." "..ent:GetFlexWeight(i) )
			end
		end
		
		self:GetOwner():ConCommand( "faceposer_scale "..ent:GetFlexScale() )	
		
		self.SWEP:UpdateFaceControlPanel( ent:EntIndex() )
			
	end
	
	/*---------------------------------------------------------
		Updates the spawn menu panel
	---------------------------------------------------------*/
	function SWEP:UpdateFaceControlPanel( index )
	
		local ent = Entity( index )
		if (!ent:IsValid()) then
			Msg("Entity not valid!\n")
		end
		local FlexNum = ent:GetFlexNum()
		// We've selected a new entity - rebuild the controls list
		local CPanel = GetControlPanel( "FacePoser" )
		
		if (CPanel != nil) then
		
			CPanel:ClearControls()
			CPanel:AddHeader()
			CPanel:AddDefaultControls()
			
	
			local params = {}
				params.Label = "#FacePoser_scale"
				params.Type = "Float"
				params.Min = "-1"
				params.Max = "20"
				params.Command = "faceposer_scale"
				
				CPanel:AddControl( "Slider", params )
				
			local params = {}
				params.Text = "#FacePoser_randomize"
				params.Command = "faceposer_randomize"
				
				CPanel:AddControl( "Button", params )
			
			for i=0, FlexNum-EYE_END do
					
				local params = {}
				params.Label = "#" .. ent:GetFlexName( i ) // # so we can language them up - is it worth $10 yet?
				params.Type = "Float"
				params.Min, params.Max = ent:GetFlexBounds( i )
				params.Command = "faceposer_flex"..i
				
				CPanel:AddControl( "Slider", params )
				
			end
		
		end
	
	end
	
	TOOL.FacePoser	= surface.GetTextureID( "gui/faceposer_indicator" )
	
	/*---------------------------------------------------------
	   Draw a box indicating the face we have selected
	---------------------------------------------------------*/
	function TOOL:DrawHUD()

		local selected = self:GetWeapon():GetNetworkedEntity( 1 )
		
		if (!selected:IsValid()) then return end
		
		local vEyePos = selected:EyePos()
		
		local eyeattachment = selected:LookupAttachment( "eyes" )
		if (eyeattachment == 0) then return end
		
		local attachment = selected:GetAttachment( eyeattachment )
		local scrpos = attachment.Pos:ToScreen()
		if (!scrpos.visible) then return end
		
		// Work out the side distance to give a rough headsize box..
		local player_eyes = LocalPlayer():EyeAngles()
		local side = (attachment.Pos + player_eyes:Right() * 20):ToScreen()
		local size = math.abs( side.x - scrpos.x )
		
		surface.SetDrawColor( 255, 255, 255, 255 )
		surface.SetTexture( self.FacePoser )
		surface.DrawTexturedRect( scrpos.x-size, scrpos.y-size, size*2, size*2 )

	end
	
end
