if ( SERVER ) then
	AddCSLuaFile( "shared.lua" )
	SWEP.Weight				= 5
	SWEP.AutoSwitchTo		= false
	SWEP.AutoSwitchFrom		= false
	SWEP.HoldType			= "smg"
end

SWEP.Author = "Silverlan"
SWEP.Contact = "Silverlan@gmx.de"
SWEP.Purpose = ""
SWEP.Instructions = ""
SWEP.Base = "base_swep_tf"
SWEP.Category		= "Team Fortress 2"

SWEP.Spawnable = true
SWEP.AdminSpawnable = true

SWEP.ViewModel = "models/weapons/v_models/v_builder_engineer.mdl"
SWEP.WorldModel = "models/weapons/w_models/w_toolbox.mdl"

SWEP.Primary.Delay			= 0.8

SWEP.Primary.ClipSize		= -1
SWEP.Primary.DefaultClip	= -1
SWEP.Primary.Automatic		= false
SWEP.Primary.ShootInWater		= true
SWEP.Primary.Ammo			= "none"

SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = true
SWEP.Secondary.Ammo = "none"

/*---------------------------------------------------------
---------------------------------------------------------*/
function SWEP:Initialize()
	self.blueprint_rotation = 0
	self.rotate = 0
end

/*---------------------------------------------------------
   Name: SWEP:Deploy( )
   Desc: Whip it out
---------------------------------------------------------*/
function SWEP:Deploy( )
	if !self then return end
	if self.Owner:Team() == 1 then self.Owner:GetViewModel():SetSkin(1) end
	
	self.blueprint_rotation = 0
	self.rotate = 0
	self.rotating = false

	self.reloading = false
	self.r_emit = false
	self.add_prim = nil
	
	self:Draw()
	return true
end

function SWEP:Draw()
	self.Weapon:SendWeaponAnim(ACT_VM_DRAW)
	timer.Create( "VM_Idle_anim_timer_2" .. self:EntIndex(), 0.8, 1, function() if self.Owner and (self.Owner:IsNPC() or ( self.Owner:IsPlayer() and self.Owner:GetActiveWeapon( ) == self )) then self:SendWeaponAnim( ACT_VM_IDLE ) end end )
	return true
end

function SWEP:Item( itemint )
	local blueprint
	if itemint == 1 then
		if self.Owner.sentry and ValidEntity(self.Owner.sentry) then return end
		blueprint = "sentry1_blueprint.mdl"
	elseif itemint == 2 then
		if self.Owner.dispenser and ValidEntity(self.Owner.dispenser) then return end
		blueprint = "dispenser_blueprint.mdl"
	elseif itemint == 3 then
		if self.Owner.tp_entrance and ValidEntity(self.Owner.tp_entrance) then return end
		blueprint = "teleporter_blueprint_enter.mdl"
	else
		if self.Owner.tp_exit and ValidEntity(self.Owner.tp_exit) then return end
		blueprint = "teleporter_blueprint_exit.mdl"
	end
	
	self:CallOnClient( "ItemChosen", "itemint" )
	self.itemchosen = true
	self.Owner:GetViewModel():SetModel( "models/weapons/v_models/v_toolbox_engineer.mdl" )
	
	self.blueprint = ents.Create( "prop_dynamic_override" )
	self.blueprint:SetModel( "models/buildables/" .. blueprint )
	self.blueprint:SetKeyValue( "solid", "0" )
	self.blueprint:SetKeyValue( "gmod_allowphysgun", "0" )
	self.blueprint:SetKeyValue( "gmod_allowtools", "0" )
	self.blueprint:Spawn()
	self.blueprint:Activate()
	
	if itemint == 1 then
		if self.Owner:Team() == 1 then
			self.blueprint:SetSkin(1)
		end
		self.blueprint:SetBodygroup(1,1)
	end
	
	for k, v in pairs(player:GetAll()) do
		if v != self.Owner then
			v:SendLua( "ents.GetByIndex(" .. self.blueprint:EntIndex() .. "):SetColor(255,255,255,0)" )
		end
	end
end

function SWEP:StopPrimaryAttack()
	if self.blueprint and ValidEntity(self.blueprint) then self.blueprint:Remove(); self.blueprint = nil end
	self.targetitem = nil
	self.itemchosen = false
	self:CallOnClient( "ItemChosen", "false" )
end

/*---------------------------------------------------------
   Name: OnRemove
   Desc: Called just before entity is deleted
---------------------------------------------------------*/
function SWEP:OnRemove()
	self:StopPrimaryAttack()
end

function SWEP:Think()
	if CLIENT then return end
	if !self.itemchosen and self.targetitem then
		self:Item(self.targetitem)
		return
	end
	if self.blueprint then
		if self.rotating then
			if self.blueprint_rotation > self.rotate then
				self.rotate = self.rotate +2.5
			elseif self.blueprint_rotation == self.rotate then
				self.rotating = false
			end
		end
	
		local pos = self.Owner:GetShootPos()
		local ang = self.Owner:GetAimVector()
		local tracedata = {}
		tracedata.start = pos
		tracedata.endpos = pos+(ang*90)
		tracedata.filter = self.Owner
		local trace = util.TraceLine(tracedata) 
		local targetpos = trace.HitPos
		targetpos.z = self.Owner:GetPos().z
		self.blueprint:SetPos( targetpos )
		self.blueprint:SetAngles( Angle(0,self.Owner:GetAngles().y +self.rotate,0) )
		
		if !trace.HitWorld then
			local pos = self.Owner:GetShootPos()
			local tracedata = {}
			tracedata.start = pos
			tracedata.endpos = targetpos -Vector(0,0,5)
			tracedata.filter = self.Owner
			trace = util.TraceLine(tracedata) 
		end
		
		local function CheckNormal()
			if trace.HitNormal.x <= 0.0003 and trace.HitNormal.y <= 0.0003 and trace.HitNormal.z <= 1 and trace.HitNormal.x >= -0.0003 and trace.HitNormal.y >= -0.0003 and trace.HitNormal.z >= 0.98 then return true else return false end
		end
		
		local anim_reject
		local anim_idle
		if string.find( self.blueprint:GetModel(), "teleporter_blueprint_enter.mdl" ) then
			anim_idle = "enter_idle"
			anim_reject = "enter_reject"
		elseif string.find( self.blueprint:GetModel(), "teleporter_blueprint_exit.mdl" ) then
			anim_idle = "exit_idle"
			anim_reject = "exit_reject"
		else
			anim_idle = "idle"
			anim_reject = "reject"
		end
		
		if !trace.HitWorld or !CheckNormal() then
			self.allowbuild = false
			self.blueprint:Fire( "SetAnimation", anim_reject, 0 )
			self.blueprint:Fire( "SetDefaultAnimation", anim_reject, 0 )
		else
			self.allowbuild = true
			self.blueprint:Fire( "SetAnimation", anim_idle, 0 )
			self.blueprint:Fire( "SetDefaultAnimation", anim_idle, 0 )
		end
	end
	
	if self.idledelay and CurTime() > self.idledelay then
		self.idledelay = nil
		self:SendWeaponAnim( ACT_VM_IDLE )
	end
end

/*---------------------------------------------------------
	PrimaryAttack
---------------------------------------------------------*/
function SWEP:PrimaryAttack()
	self.Weapon:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
	self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
	
	if !self.itemchosen or !self.allowbuild then return end
	
	local SpawnPos = self.blueprint:GetPos()//(tr.HitPos + tr.HitNormal * 16) -Vector( 0, 0, 17 )
	local SpawnAngles = self.Owner:GetAngles()
	SpawnAngles.pitch = 0
	SpawnAngles.roll = 0
	SpawnAngles.yaw = SpawnAngles.y +self.blueprint_rotation
	
	local building
	local undostring
	local metal
	if self.targetitem == 1 then
		if self.Owner.sentry and ValidEntity(self.Owner.sentry) then return end
		building = "obj_sentrygun"
		undostring = "Undone Sentry"
		self.Owner:EmitSound( "vo/engineer_autobuildingsentry0" .. math.random(1,2) .. ".wav", 100, 100 )
		metal = 130
	elseif self.targetitem == 2 then
		if self.Owner.dispenser and ValidEntity(self.Owner.dispenser) then return end
		building = "obj_dispenser"
		undostring = "Undone Dispenser"
		metal = 100
	elseif self.targetitem == 3 then
		if self.Owner.tp_entrance and ValidEntity(self.Owner.tp_entrance) then return end
		building = "obj_teleporter_entrance"
		undostring = "Undone Teleporter entrance"
		metal = 125
	else
		if self.Owner.tp_exit and ValidEntity(self.Owner.tp_exit) then return end
		building = "obj_teleporter_exit"
		undostring = "Undone Teleporter exit"
		metal = 125
	end
	self.Owner:SetNetworkedInt( "ammo_metal", self.Owner:GetNetworkedInt( "ammo_metal" ) -metal )
	local obj = ents.Create( building )
	obj.owner = self.Owner
	//obj:SetOwner( self.Owner )
	obj:SetNetworkedEntity( "owner", self.Owner )
	obj:SetPos( SpawnPos )
	obj:SetAngles( SpawnAngles )
	obj:Spawn()
	obj:Activate()
	obj:SetUp()
	obj:SetNetworkedBool( "building", true )
	
	if self.targetitem == 1 then
		self.Owner.sentry = obj
		self.Owner:SetNetworkedEntity( "sentrygun", obj )
	elseif self.targetitem == 2 then
		self.Owner.dispenser = obj
		self.Owner:SetNetworkedEntity( "dispenser", obj )
	elseif self.targetitem == 3 then
		self.Owner.tp_entrance = obj
		self.Owner:SetNetworkedEntity( "tp_entrance", obj )
	elseif self.targetitem == 4 then
		self.Owner.tp_exit = obj
		self.Owner:SetNetworkedEntity( "tp_exit", obj )
	end
	
	if GAMEMODE.IsSandboxDerived then
		undo.Create("NPC")
		undo.SetCustomUndoText(undostring)
		undo.AddEntity(obj)
		undo.SetPlayer(self.Owner)
		undo.Finish() 
	end
	
	// In singleplayer this function doesn't get called on the client, so we use a networked float
	// to send the last shoot time. In multiplayer this is predicted clientside so we don't need to 
	// send the float.
	if ( (SinglePlayer() && SERVER) || CLIENT ) then
		self.Weapon:SetNetworkedFloat( "LastShootTime", CurTime() )
	end
	 self.Owner:SelectWeapon( "tf_weapon_wrench" ) 
end

SWEP.NextSecondaryAttack = 0
/*---------------------------------------------------------
	SecondaryAttack
---------------------------------------------------------*/
function SWEP:SecondaryAttack()
	if self.rotating then return end
	self.rotating = true
	self.blueprint_rotation = self.blueprint_rotation +90
end
