local Driver = Class(function(self, inst)
    self.inst = inst
    self.driving = false
    self.cachedrunspeed = nil
    self.mountdata = nil
    self.combined = false 
    self.durabilitymultiplier = 1
    self.cachedRadius = nil
    self.warningthresholds = 
    {
    	{percent = 0.5, string = "ANNOUNCE_BOAT_DAMAGED"},
    	{percent = 0.3, string = "ANNOUNCE_BOAT_SINKING"},
    	{percent = 0.1, string = "ANNOUNCE_BOAT_SINKING_IMMINENT"},
	}
end)

--[[
function Driver:OnSave()
	local data = {}
	local refs = {}

	data.driving = self.driving 

	if self.vehicle then 
		table.insert(refs, self.vehicle.GUID)
		data.vehicle = self.vehicle.GUID
	end 
	print("driver being saved!")
	return data, refs
end   

function Driver:LoadPostPass(ents, data)
	if data.driving and data.vehicle then

		local vehicle = ents[data.vehicle].entity
		self:OnMount(vehicle)
	end
	print("driver being post loaded!")
end

function Driver:OnLoad(data)
	
	
end  
]] 

function Driver:OnUpdate(dt) --Set my entity's position and rotation to be the same as the drivable entity's 
    
    if self.vehicle ~= nil then 
    	local myPos = self.inst:GetPosition()
        --local pos = self.vehicle:GetPosition()
		
		local CameraRight = TheCamera:GetRightVec()
        local CameraDown = TheCamera:GetDownVec()
        
        local displacement = CameraRight:Cross(CameraDown) * 0.2
		
----------------------MOD-------------------------------

		local displace_xz = 0.3--0.3
		
		local heading_angle = -(GetPlayer().Transform:GetRotation())
		print("============================MODED DRIVER==================")
		local dir = Vector3(math.cos(heading_angle*DEGREES),0, math.sin(heading_angle*DEGREES))
		print("dir.x"..dir.x)
		--self.inst.Transform:SetPosition(myPos.x-dir.x*displace_xz , myPos.y, myPos.z-dir.z*displace_xz)
		local pos = myPos-displacement
		local newx, newz = pos.x-dir.x*displace_xz, pos.z-dir.z*displace_xz
		print("poss"..pos.x)
		print("newx"..newx)
       	self.vehicle.Transform:SetPosition( newx, pos.y, newz)

-------------------------------end mod
		
		
		
		
		
		
		
       	if self.vehicle.components.boathealth then 
       		self.vehicle.components.boathealth.depletionmultiplier = 1.0/self.durabilitymultiplier
       	end 
     	if(self.combined == true ) then 
       		self.vehicle.Transform:SetRotation(self.inst.Transform:GetRotation())
       	end 
    end
end

function Driver:OnDismount(death, pos, boat_to_boat)
	self.driving = false
	self.inst:StopUpdatingComponent(self)
	if(self.mountdata) then 
		local x, y, z = self.inst.Transform:GetWorldPosition()
    	local mount = SpawnSaveRecord(self.mountdata, {})
    	mount.Physics:Teleport(x, y, z)
    	mount.Transform:SetRotation(self.inst.Transform:GetRotation())
	end 

	if self.vehicle.onboatdelta then
		self.inst:RemoveEventCallback("boathealthchange", self.vehicle.onboatdelta, self.vehicle)
		self.vehicle.onboatdelta = nil
	end

	self:SplitFromVehicle()
	
	if self.vehicle.components.container then 
		self.vehicle.components.container:Close(self.inst)
	end

	if self.inst.components.farseer then
		self.inst.components.farseer:RemoveBonus("boat")
	end

	if self.inst:HasTag("pirate") then
		self.vehicle.components.drivable.sanitydrain = self.cachedsanitydrain
		self.cachedsanitydrain = nil
	end

    -- self.inst.AnimState:SetBank("wilson")
    -- self.inst.AnimState:SetBuild(self.inst.prefab)
	
	
	---////---MOD
  --  self.inst.AnimState:ClearOverrideBuild(self.vehicle.components.drivable.overridebuild)
	----///--end mod
	
    self.inst.components.locomotor.directdrive = false
    self.inst.components.locomotor.hasmomentum = false
    self.inst.components.locomotor.runspeed = self.cachedrunspeed

 	local position = self.inst:GetPosition()
    MakeCharacterPhysics(self.inst, 75, self.cachedRadius)
    self.inst.Physics:SetActive(true)
    self.inst.Transform:SetPosition(position.x, position.y, position.z) --Calling set active can change the position, make sure we're where we want to me 

    self.cachedrunspeed = nil
    self.inst:SetStateGraph(self.landstategraph)
	self.inst:RemoveTag("aquatic")
	self.inst:PushEvent("dismountboat", {boat = self.vehicle})

	if(self.onStopDriving) then
		self.onStopDriving(self.inst)
	end

	--local vehiclePos = self.vehicle:GetPosition()

	self.vehicle.components.drivable:OnDismounted(self.inst)
	self.vehicle = nil

	if self.inst.components.leader then 
		self.inst.components.leader:RemoveWaterFollowers()
	end 

	if pos then
		self.inst.sg:GoToState("jumpoffboatstart", pos)
	elseif boat_to_boat then
		self.inst.sg:GoToState("jumponboatstart")
	end
end

function Driver:OnMount(vehicle)
	self.driving = true 
	self.vehicle = vehicle

	if self.inst:HasTag("pirate") then
		self.cachedsanitydrain = vehicle.components.drivable.sanitydrain
		vehicle.components.drivable.sanitydrain = 0
	end

	self.inst:StartUpdatingComponent(self)

	-- self.inst.AnimState:SetBank("wilson")
    -- self.inst.AnimState:SetBuild(self.inst.prefab)
	
		---////---MOD
--    self.inst.AnimState:AddOverrideBuild(self.vehicle.components.drivable.overridebuild)
 --   self.inst.AnimState:OverrideSymbol("flotsam", self.vehicle.components.drivable.flotsambuild, "flotsam")

	----///--end mod
	
	
	
	self.inst:SetStateGraph(self.boatingstategraph)
	self.inst:AddTag("aquatic")
	self.inst.sg:GoToState("jumpboatland")
	--self.inst:PushEvent("landboat")
	--Snap the player to the vehicle position
	local vehiclePos = vehicle:GetPosition()
	self.inst.Transform:SetPosition(vehiclePos.x , vehiclePos.y, vehiclePos.z)
	
	self.cachedrunspeed = self.inst.components.locomotor.runspeed
	self.inst.components.locomotor.runspeed = vehicle.components.drivable.runspeed
	
	--self.inst.components.locomotor.directdrive = true
	self.inst.components.locomotor.hasmomentum = true
	self.inst.components.locomotor.bargle = true --for debugging 

	self.cachedRadius = self.inst.Physics:GetRadius() 

	local position = self.inst:GetPosition()
	MakeCharacterPhysics(self.inst, 75, 1)
	self.inst.Physics:SetActive(true)

	--Listen for boat taking damage, talk if it is!
	vehicle.onboatdelta = function(boat, data)
		if data then
			local old = data.oldpercent
			local new = data.percent
			local message = nil
			for _, threshold in ipairs(self.warningthresholds) do
				if old > threshold.percent and new <= threshold.percent then
					message = threshold.string
				end
			end

			if message then
				self.inst:PushEvent("boat_damaged", {message = message})
			end
		end
	end
	self.inst:ListenForEvent("boathealthchange", vehicle.onboatdelta, vehicle)

	if vehicle.components.boathealth then
		local percent = vehicle.components.boathealth:GetPercent()
		vehicle.onboatdelta(vehicle, {oldpercent = 1, percent = percent})
	end

	if self.inst.components.farseer and vehicle.components.drivable and vehicle.components.drivable.maprevealbonus then
		self.inst.components.farseer:AddBonus("boat", vehicle.components.drivable.maprevealbonus)
	end

	if vehicle.components.container then
		if vehicle.components.container:IsOpen() then
			vehicle.components.container:Close()
		end
		self.inst:DoTaskInTime(0.1, function() vehicle.components.container:Open(self.inst) end) --Not sure why but when loading a game where you're in a boat this doesn't work unless it's delayed
	end 

	if self.inst.components.leader then 
		self.inst.components.leader:RemoveLandFollowers()
	end 

	self.inst:PushEvent("mountboat", {boat = self.vehicle})
	if(self.onStartDriving) then 
		self.onStartDriving(self.inst)
	end
	self:CombineWithVehicle()
	return true
end

function Driver:GetIsDriving()
	return self.vehicle ~= nil
end 

function Driver:GetIsSailing()
	if self.vehicle then 
		return self.vehicle.components.drivable:GetIsSailEquipped()
	end 
end 

function Driver:CombineWithVehicle()
	self.combined = true 
	--self.vehicle:Hide()
end 

function Driver:SplitFromVehicle()
	self.combined = false 
	self.vehicle:Show()
end 


return Driver
