// Variables that are used on both client and server

SWEP.Author			= ""
SWEP.Contact			= ""
SWEP.Purpose			= ""
SWEP.Instructions		= ""

SWEP.ViewModel			= "models/weapons/v_toolgun.mdl"
SWEP.WorldModel			= "models/weapons/w_toolgun.mdl"
SWEP.AnimPrefix			= "python"

// Be nice, precache the models
util.PrecacheModel( SWEP.ViewModel )
util.PrecacheModel( SWEP.WorldModel )

// Todo, make/find a better sound.
SWEP.ShootSound			= Sound( "Airboat.FireGunRevDown" )

SWEP.Tool				= {}

SWEP.Primary = 
{
	ClipSize 	= -1,
	DefaultClip = -1,
	Automatic = false,
	Ammo = "none"
}

SWEP.Secondary = 
{
	ClipSize 	= -1,
	DefaultClip = -1,
	Automatic = false,
	Ammo = "none"
}

SWEP.CanHolster			= true
SWEP.CanDeploy			= true

function SWEP:InitializeTools()

	local temp = {}
	
	for k,v in pairs( self.Tool ) do
		temp[k] = table.Copy(v)
		temp[k].SWEP = self
		temp[k].Owner = self.Owner
		temp[k].Weapon = self.Weapon
	end
	
	self.Tool = temp
	
end

/*---------------------------------------------------------
	Initialize
---------------------------------------------------------*/
function SWEP:Initialize()

	self:InitializeTools()
	
	// We create these here. The problem is that these are meant to be constant values.
	// in the toolmode they're not because some tools can be automatic while some tools aren't.
	// Since this is a global table it's shared between all instances of the gun.
	// By creating new tables here we're making it so each tool has its own instance of the table
	// So changing it won't affect the other tools.
	
	self.Primary = 
	{
		// Note: Switched this back to -1.. lets not try to hack our way around shit that needs fixing. -gn
		ClipSize 	= -1,
		DefaultClip = -1,
		Automatic = false,
		Ammo = "none"
	}
	
	self.Secondary = 
	{
		ClipSize 	= -1,
		DefaultClip = -1,
		Automatic = false,
		Ammo = "none"
	}
	
end


/*---------------------------------------------------------
	OnRestore
---------------------------------------------------------*/
function SWEP:OnRestore()

	self:InitializeTools()
	
end

/*---------------------------------------------------------
   Precache Stuff
---------------------------------------------------------*/
function SWEP:Precache()

	util.PrecacheSound( self.ShootSound )
	
end

/*---------------------------------------------------------
	Reload clears the objects
---------------------------------------------------------*/
function SWEP:Reload()

	// This makes the reload a semi-automatic thing rather than a continuous thing
	if ( !self.Owner:KeyPressed( IN_RELOAD ) ) then return end

	local mode = self:GetMode()
	local tr = util.GetPlayerTrace( self.Owner )
	local trace = util.TraceLine( tr )
	if (!trace.Hit) then return end
	
	local tool = self:GetToolObject()
	if ( !tool ) then return end
	
	tool:CheckObjects()
	
	// Does the server setting say it's ok?
	if ( !tool:Allowed() ) then return end
	
	// Ask the gamemode if it's ok to do this
	if ( !gamemode.Call( "CanTool", self.Owner, trace, mode ) ) then return end
	
	if ( !tool:Reload( trace ) ) then return end
	
	self:DoShootEffect( trace.HitPos, trace.HitNormal, trace.Entity, trace.PhysicsBone )
	
end

/*---------------------------------------------------------
	Returns the mode we're in
---------------------------------------------------------*/
function SWEP:GetMode()
	
	return self.Mode
	
end

/*---------------------------------------------------------
	Think does stuff every frame
---------------------------------------------------------*/
function SWEP:Think()

	self.Mode = self.Owner:GetInfo( "gmod_toolmode" )
	local mode = self:GetMode()
	local tool = self:GetToolObject()
	
	if ( !tool ) then return end
	
	tool:CheckObjects()
	
	self.last_mode 		= self.current_mode
	self.current_mode 	= mode
	
	// Release ghost entities if we're not allowed to use this new mode?
	if ( !tool:Allowed() ) then 
		self:GetToolObject( self.last_mode ):ReleaseGhostEntity() 
		return 
	end
	
	if ( self.last_mode != self.current_mode ) then
	
		if ( !self:GetToolObject( self.last_mode ) ) then return end
		
		// We want to release the ghost entity just in case
		self:GetToolObject( self.last_mode ):Holster()
		
	end
	
	self.Primary.Automatic 		= tool.LeftClickAutomatic 	or false
	self.Secondary.Automatic 	= tool.RightClickAutomatic 	or false
	self.RequiresTraceHit 		= tool.RequiresTraceHit 	or true
	
	tool:Think()
	
end


/*---------------------------------------------------------
	The shoot effect
---------------------------------------------------------*/
function SWEP:DoShootEffect( hitpos, hitnormal, entity, physbone )

	self.Weapon:EmitSound( self.ShootSound	)
	self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) 	// View model animation
	
	// There's a bug with the model that's causing a muzzle to 
	// appear on everyone's screen when we fire this animation. 
	//self.Owner:SetAnimation( PLAYER_ATTACK1 )			// 3rd Person Animation
	
	local effectdata = EffectData()
		effectdata:SetOrigin( hitpos )
		effectdata:SetNormal( hitnormal )
		effectdata:SetEntity( entity )
		effectdata:SetAttachment( physbone )
	util.Effect( "selection_indicator", effectdata )	
	
	local effectdata = EffectData()
		effectdata:SetOrigin( hitpos )
		effectdata:SetStart( self.Owner:GetShootPos() )
		effectdata:SetAttachment( 1 )
		effectdata:SetEntity( self.Weapon )
	util.Effect( "ToolTracer", effectdata )
	
end

/*---------------------------------------------------------
	Trace a line then send the result to a mode function
---------------------------------------------------------*/
function SWEP:PrimaryAttack()

	local mode = self:GetMode()
	local tr = util.GetPlayerTrace( self.Owner )
	local trace = util.TraceLine( tr )
	if (!trace.Hit) then return end
	
	local tool = self:GetToolObject()
	if ( !tool ) then return end
	
	tool:CheckObjects()
	
	// Does the server setting say it's ok?
	if ( !tool:Allowed() ) then return end
	
	// Ask the gamemode if it's ok to do this
	if ( !gamemode.Call( "CanTool", self.Owner, trace, mode ) ) then return end
	
	if ( !tool:LeftClick( trace ) ) then return end
	
	self:DoShootEffect( trace.HitPos, trace.HitNormal, trace.Entity, trace.PhysicsBone )
	
end


/*---------------------------------------------------------
	SecondaryAttack - Reset everything to how it was
---------------------------------------------------------*/
function SWEP:SecondaryAttack()

	local mode = self:GetMode()
	local tr = utilx.GetPlayerTrace( self.Owner )
	local trace = util.TraceLine( tr )
	if (!trace.Hit) then return end
	
	local tool = self:GetToolObject()
	if ( !tool ) then return end
	
	tool:CheckObjects()
	
	// Ask the gamemode if it's ok to do this
	if ( !tool:Allowed() ) then return end
	if ( !gamemode.Call( "CanTool", self.Owner, trace, mode ) ) then return end
	
	if ( !tool:RightClick( trace ) ) then return end

	self:DoShootEffect( trace.HitPos, trace.HitNormal, trace.Entity, trace.PhysicsBone )
	
end

/*---------------------------------------------------------
   Name: ContextScreenClick(  aimvec, mousecode, pressed, ply )
---------------------------------------------------------*/
function SWEP:ContextScreenClick( aimvec, mousecode, pressed, ply )

	if ( !pressed ) then return end
	
	// No prediction in single player
	if (CLIENT && SinglePlayer()) then return end 
	
	local ViewEnt = ply
	
	if (CLIENT) then ViewEnt = GetViewEntity() end
	if (SERVER) then ViewEnt = ply:GetViewEntity() end
	
	local mode = self:GetMode()
	local tr = utilx.GetPlayerTrace( ViewEnt, aimvec )
	local trace = util.TraceLine( tr )
	if ( !trace.Hit ) then return end
	
	local tool = self:GetToolObject()
	if ( !tool ) then return end
	
	tool:CheckObjects()
	
	// Ask the gamemode if it's ok to do this
	if ( !tool:Allowed() ) then return end
	if ( !gamemode.Call( "CanTool", self.Owner, trace, mode ) ) then return end
	
	if ( mousecode == MOUSE_LEFT ) then
		if ( !tool:LeftClick( trace ) ) then return end
	else
		if ( !tool:RightClick( trace ) ) then return end
	end
	
	self:DoShootEffect( trace.HitPos, trace.HitNormal, trace.Entity, trace.PhysicsBone )
	
end

/*---------------------------------------------------------
	Holster
---------------------------------------------------------*/
function SWEP:Holster()

	// Just do what the SWEP wants to do if there's no tool
	if ( !self:GetToolObject() ) then return self.CanHolster end
	
	local CanHolster = self:GetToolObject():Holster()
	if ( CanHolster ~= nil ) then return CanHolster end
	
	return self.CanHolster
	
end

/*---------------------------------------------------------
	OnRemove
	- Delete ghosts here in case the weapon gets deleted all of a sudden somehow
---------------------------------------------------------*/
function SWEP:OnRemove()

	if ( !self:GetToolObject() ) then return end
	
	self:GetToolObject():ReleaseGhostEntity()
	
end


/*---------------------------------------------------------
	OwnerChanged
	- This will remove any ghosts when a player dies and drops the weapon
---------------------------------------------------------*/
function SWEP:OwnerChanged()

	if ( !self:GetToolObject() ) then return end
	
	self:GetToolObject():ReleaseGhostEntity()
	
end

/*---------------------------------------------------------
	Deploy
---------------------------------------------------------*/
function SWEP:Deploy()

	// Just do what the SWEP wants to do if there is no tool
	if ( !self:GetToolObject() ) then return self.CanDeploy end
	
	self:GetToolObject():UpdateData()
	
	local CanDeploy = self:GetToolObject():Deploy()
	if ( CanDeploy ~= nil ) then return CanDeploy end
	
	return self.CanDeploy
	
end

function SWEP:GetToolObject( tool )
	
	local mode = tool or self:GetMode()
	
	if ( !self.Tool[ mode ] ) then return false end
	
	return self.Tool[ mode ]
	
end

include( 'stool.lua' )
