--***********************************************************
--**                    THE INDIE STONE                    **
--***********************************************************

require "ISUI/ISPanelJoypad"

ISVehicleSeatUI = ISPanelJoypad:derive("ISVehicleSeatUI")

function ISVehicleSeatUI:createChildren()
	local btnWid = 100
	local btnHgt = 25
	local padBottom = 10

	self.close = ISButton:new((self:getWidth() - btnWid) / 2, self:getHeight() - padBottom - btnHgt,
							  btnWid, btnHgt, getText("UI_Cancel"), self, ISVehicleSeatUI.closeSelf)
	self.close.internal = "CLOSE"
	self.close.anchorTop = false
	self.close.anchorBottom = true
	self.close:initialise()
	self.close:instantiate()
	self.close.borderColor = {r=1, g=1, b=1, a=0.1}
	self:addChild(self.close)
end

function ISVehicleSeatUI:prerender()
	ISPanelJoypad.prerender(self)

	if not self.vehicle then return end
	local script = self.vehicle:getScript()

	if self.mouseOverExit then
		self:drawTextCentre(getText("IGUI_ExitVehicle"), self:getWidth() / 2, 6, 1, 1, 1, 1, UIFont.Medium)
		return
	end

	local seat = self.joyfocus and (self.joypadSeat - 1) or self.mouseOverSeat
	if not seat then return end
	local seatname = 'Seat'..script:getPassenger(seat):getId()
	if getText("IGUI_" .. seatname) ~= "IGUI_" .. seatname then
		seatname = getText("IGUI_" .. seatname);
	end
	self:drawTextCentre(seatname, self:getWidth() / 2, 6, 1, 1, 1, 1, UIFont.Medium)
	local str = nil
	-- FIXME: can player sit where there is no seat installed?
	if not self:isSeatInstalled(seat) then
		str = getText("IGUI_VehicleSeat_Uninstalled")
	elseif self.vehicle:isSeatOccupied(seat) then
		if not ISVehicleMenu.moveItemsFromSeat(self.character, self.vehicle, seat, false, false) then
			str = getText("IGUI_VehicleSeat_Items")
		else
			str = getText("IGUI_VehicleSeat_MoveItems")
		end
		if self.characterSeat == seat then
			str = getText("IGUI_VehicleSeat_Self")
		elseif self.vehicle:getCharacter(seat) then
			str = getText("IGUI_VehicleSeat_Person")
		end
	end
	if str then
		local fontHgt = getTextManager():getFontFromEnum(UIFont.Medium):getLineHeight()
		self:drawTextCentre(str, self:getWidth() / 2, 6 + fontHgt, 1, 0, 0, 1, UIFont.Small)
	end
end

local ImageScale = {}
ImageScale["4door_"] = 1.0
ImageScale["offroad_"] = 1.0
ImageScale["smallcar_"] = 1.1
ImageScale["sportscar_"] = 1.15
ImageScale["stationwagon_"] = 1.15
ImageScale["suv_"] = 1.0
ImageScale["truck_"] = 1.1
ImageScale["van_"] = 1.1

local SeatOffsetY = {}
SeatOffsetY["Base.CarNormal"] = 4
SeatOffsetY["Base.CarTaxi"] = SeatOffsetY["Base.CarNormal"]
SeatOffsetY["Base.CarTaxi2"] = SeatOffsetY["Base.CarNormal"]
SeatOffsetY["Base.PickUpTruck"] = 3
SeatOffsetY["Base.PickUpVan"] = SeatOffsetY["Base.PickUpTruck"]
SeatOffsetY["Base.PickUpVanLights"] = SeatOffsetY["Base.PickUpTruck"]
SeatOffsetY["Base.PickUpVanLightsFire"] = SeatOffsetY["Base.PickUpTruck"]
SeatOffsetY["Base.PickUpTruckLightsFire"] = SeatOffsetY["Base.PickUpTruck"]
SeatOffsetY["Base.PickUpTruckLights"] = SeatOffsetY["Base.PickUpTruck"]
SeatOffsetY["Base.SmallCar"] = 15
SeatOffsetY["Base.SmallCar02"] = 0
SeatOffsetY["Base.CarStationWagon"] = -9
SeatOffsetY["Base.CarLuxury"] = 0
SeatOffsetY["Base.SportsCar"] = -6
SeatOffsetY["Base.StepVan"] = -3;
SeatOffsetY["Base.Van"] = 3;
SeatOffsetY["Base.VanAmbulance"] = SeatOffsetY["Base.Van"];
SeatOffsetY["Base.VanSeats"] = SeatOffsetY["Base.StepVan"];
SeatOffsetY["Base.ModernCar"] = 7;
SeatOffsetY["Base.ModernCar02"] = 15;
SeatOffsetY["Base.SUV"] = -2
SeatOffsetY["Base.OffRoad"] = 30

local SeatOffsetX = {}
SeatOffsetX["Base.PickUpTruck"] = 0;
SeatOffsetX["Base.PickUpVan"] = SeatOffsetX["Base.PickUpTruck"]
SeatOffsetX["Base.PickUpVanLights"] = SeatOffsetX["Base.PickUpTruck"];
SeatOffsetX["Base.PickUpVanLightsFire"] = SeatOffsetX["Base.PickUpTruck"]
SeatOffsetX["Base.PickUpTruckLightsFire"] = SeatOffsetX["Base.PickUpTruck"]
SeatOffsetX["Base.PickUpTruckLights"] = SeatOffsetX["Base.PickUpTruck"]
SeatOffsetX["Base.SmallCar"] = 0;
SeatOffsetX["Base.SmallCar02"] = SeatOffsetX["Base.SmallCar"];
SeatOffsetX["Base.CarStationWagon"] = 0;
SeatOffsetX["Base.CarNormal"] = 0;
SeatOffsetX["Base.CarTaxi"] = SeatOffsetX["Base.CarNormal"]
SeatOffsetX["Base.CarTaxi2"] = SeatOffsetX["Base.CarNormal"]
SeatOffsetX["Base.StepVan"] = 0;
SeatOffsetX["Base.Van"] = 0;
SeatOffsetX["Base.VanSeats"] = SeatOffsetX["Base.StepVan"];
SeatOffsetX["Base.VanAmbulance"] = SeatOffsetX["Base.Van"];
SeatOffsetX["Base.CarLuxury"] = 0
SeatOffsetX["Base.SportsCar"] = 0
SeatOffsetX["Base.ModernCar"] = 0;
SeatOffsetX["Base.ModernCar02"] = SeatOffsetX["Base.ModernCar"];
SeatOffsetX["Base.SUV"] = 0
SeatOffsetX["Base.OffRoad"] = 2

function ISVehicleSeatUI:render()
	ISPanelJoypad.render(self)

	self.mouseOverSeat = nil
	self.mouseOverExit = nil

	if not self.vehicle then return end
	
	local script = self.vehicle:getScript()
	local scriptName = self.vehicle:getScriptName()
	local extents = script:getExtents()
	local ratio = extents:x() / extents:z() + 0.0
	local height = self.height * 0.7
	local width = height * ratio
	local ex = (self.width - width) / 2
	local ey = (self.height - height) / 2
	local props = ISCarMechanicsOverlay.CarList[scriptName]
	if props and props.imgPrefix then
		local tex = getTexture("media/ui/vehicles/seatui/" .. props.imgPrefix .. "base_small.png")
		if tex then
			local imageScale = ImageScale[props.imgPrefix] or 1.0
			self:drawTextureScaledUniform(tex,
				tex:getOffsetX() * imageScale + (self.width - tex:getWidthOrig() * imageScale) / 2,
				tex:getOffsetY() * imageScale + (self.height - tex:getHeightOrig() * imageScale) / 2,
				imageScale, 1,1,1,1)
		else
			self:drawRect(ex, ey, width, height, 0.8, 0.0, 0.0, 0.0)
			self:drawRectBorder(ex, ey, width, height, 1.0, 1.0, 1.0, 1.0)
		end
	else
		self:drawRect(ex, ey, width, height, 0.8, 0.0, 0.0, 0.0)
		self:drawRectBorder(ex, ey, width, height, 1.0, 1.0, 1.0, 1.0)
	end

	local playerSeat = self.vehicle:getSeat(self.character)

	local shiftKey = isKeyDown(Keyboard.KEY_LSHIFT) or isKeyDown(Keyboard.KEY_RSHIFT)

	local scale = height / extents:z() * script:getModelScale()
	local sizeX,sizeY = 41,59
	local fontHgtLarge = getTextManager():getFontFromEnum(UIFont.Large):getLineHeight()
	for seat=1,self.vehicle:getMaxPassengers() do
		local pngr = script:getPassenger(seat-1)
		local posn = pngr:getPositionById("inside")
		if posn then
			local offset = posn:getOffset()
			local x = self:getWidth() / 2 - offset:get(0) * scale - sizeX / 2
			local y = self:getHeight() / 2 - offset:get(2) * scale - sizeY / 2
			y = y + (SeatOffsetY[scriptName] or 0.0)
			
			x = x + (SeatOffsetX[scriptName] or 0.0)
		
			local mouseOver = (self:getMouseX() >= x and self:getMouseX() < x + sizeX and
					self:getMouseY() >= y and self:getMouseY() < y + sizeY) or
					(self.joyfocus and self.joypadSeat == seat)
			if mouseOver then
				self.mouseOverSeat = seat - 1
			end

			local fillR, fillG, fillB = 0.0, 0.0, 0.0
			local outlineR, outlineG, outlineB = 0.0, 1.0, 0.0
			local texName = "icon_vehicle_empty.png"
			local canSwitch = false
			if self.vehicle:isSeatOccupied(seat-1) then
				if self.vehicle:getCharacter(seat-1) then
					texName = "icon_vehicle_person.png"
					fillR = 0.0
					fillG = 0.0
					fillB = 1.0
				else
					if ISVehicleMenu.moveItemsFromSeat(self.character, self.vehicle, seat-1, false, false) then
						canSwitch = true;
						fillR, fillG, fillB = 0.0, 0.0, 0.0
						outlineR, outlineG, outlineB = 0.0, 1.0, 0.0
						texName = "icon_vehicle_empty.png"
					else
						texName = "icon_vehicle_stuff.png"
						fillR = 0.5
						fillG = 0.5
						fillB = 0.5
					end
				end
				if mouseOver then
					outlineR = 1.0
					outlineG = 0.0
					outlineB = 0.0
				end
			elseif self.vehicle:getPartForSeatContainer(seat-1) and
					not self.vehicle:getPartForSeatContainer(seat-1):getInventoryItem() then
				texName = "icon_vehicle_uninstalled.png"
				fillR = 0.5
				fillG = 0.5
				fillB = 0.5
				if mouseOver then
					outlineR = 1.0
					outlineG = 0.0
					outlineB = 0.0
				end
			else
				canSwitch = true
			end
		
		
			local tex = getTexture("media/ui/vehicles/seatui/" .. texName)
			if tex then
				self:drawTextureScaledUniform(tex, x, y, 1, 1,1,1,1)
			else
				self:drawRect(x, y, sizeX, sizeY, 1.0, fillR, fillG, fillB)
				self:drawRectBorder(x, y, sizeX, sizeY, 1.0, 1.0, 1.0, 1.0)
			end

			if not shiftKey and canSwitch and not self.joyfocus then
				self:drawTextCentre(tostring(seat), x + sizeX / 2, y + sizeY / 2 - fontHgtLarge / 2, 1, 1, 1, 1, UIFont.Large)
			end
			
			if mouseOver then
				self:drawRectBorder(x - 2, y - 2, sizeX + 4, sizeY + 4, 1.0, outlineR, outlineG, outlineB)
			end

			if canSwitch and self.joyfocus and self.joypadSeat == seat then
				local tex = getTexture("media/ui/abutton.png")
				local texW,texH = tex:getWidth(),tex:getHeight()
				local x = self:getWidth() / 2 - offset:get(0) * scale - texW / 2
				local y = self:getHeight() / 2 - offset:get(2) * scale - texH / 2
				x = x + (SeatOffsetX[scriptName] or 0.0)
				y = y + (SeatOffsetY[scriptName] or 0.0)
				self:drawTextureScaledUniform(tex, x, y, 1, 1,1,1,1)
			end
		end

		-- Display available exits when inside.
		if playerSeat ~= -1 and not self.joyfocus then
			local canSwitch = self.vehicle:canSwitchSeat(playerSeat, seat - 1)
			if self.vehicle:isSeatOccupied(seat - 1) then canSwitch = false end
			if playerSeat == seat - 1 then canSwitch = true end
			if self.vehicle:isExitBlocked(seat - 1) then canSwitch = false end
			posn = pngr:getPositionById("outside")
		-- if you can't switch because of item we check you can still move them
			if not canSwitch and not self.vehicle:getCharacter(seat-1) then
				canSwitch = ISVehicleMenu.moveItemsFromSeat(self.character, self.vehicle, seat-1, false, false);
			end
			if canSwitch and posn then
				local offset = posn:getOffset()
				local tex = getTexture("media/ui/vehicles/vehicle_exit.png")
				local texW,texH = tex:getWidth(),tex:getHeight()
				local x = self:getWidth() / 2 - offset:get(0) * scale - texW / 2
				local y = self:getHeight() / 2 - offset:get(2) * scale - texH / 2
				y = y + (SeatOffsetY[scriptName] or 0.0)

				local mouseOver = (self:getMouseX() >= x and self:getMouseX() < x + texW and
						self:getMouseY() >= y and self:getMouseY() < y + texH) or
						(self.joyfocus and self.joypadSeat == seat)
				if mouseOver then
					self.mouseOverExit = seat - 1
				end

				if mouseOver or shiftKey then
					self:drawTextureScaledUniform(tex, x, y, 1, 1,1,1,1)
				else
					self:drawTextureScaledUniform(tex, x, y, 1, 0.2,1,1,1)
				end

				if shiftKey then
					self:drawRect(x + texW / 2 - 8, y + texH / 2 - fontHgtLarge / 2, 16, fontHgtLarge, 1, 0.1, 0.1, 0.1)
					self:drawTextCentre(tostring(seat), x + texW / 2, y + texH / 2 - fontHgtLarge / 2, 1, 1, 1, 1, UIFont.Large)
				end
			end
		end
		if playerSeat ~= -1 and self.joyfocus and seat == self.joypadSeat then
			local canSwitch = self.vehicle:canSwitchSeat(playerSeat, seat - 1)
			if self.vehicle:isSeatOccupied(seat - 1) then canSwitch = false end
			if playerSeat == seat - 1 then canSwitch = true end
			if self.vehicle:isExitBlocked(seat - 1) then canSwitch = false end
			posn = pngr:getPositionById("outside")
			if canSwitch and posn then
				local offset = posn:getOffset()
				local tex = getTexture("media/ui/xbutton.png")
				local texW,texH = tex:getWidth(),tex:getHeight()
				local x = self:getWidth() / 2 - offset:get(0) * scale - texW / 2
				local y = self:getHeight() / 2 - offset:get(2) * scale - texH / 2
				y = y + (SeatOffsetY[scriptName] or 0.0)
				self:drawTextureScaledUniform(tex, x, y, 1, 1,1,1,1)
			end
		end
	end

	-- TODO: Allow choosing a seat to exit from
end

function ISVehicleSeatUI:update()
	ISPanelJoypad.update(self)
	self:centerOnScreen()
	if self.vehicle and self.character:DistTo(self.vehicle:getX(), self.vehicle:getY()) > 6 then
		self:closeSelf()
	end
end

function ISVehicleSeatUI:onMouseDown(x, y)
	if self.mouseOverSeat then
		self:useSeat(self.mouseOverSeat)
		return
	end
	if self.mouseOverExit then
		self:exitSeat(self.mouseOverExit)
		return
	end
end

function ISVehicleSeatUI:onMouseDownOutside(x, y)
	if self.playerNum == 0 then
		self:closeSelf()
	end
end

function ISVehicleSeatUI:isSeatInstalled(seat)
	if not self.vehicle then return false end
	return self.vehicle:isSeatInstalled(seat)
end

function ISVehicleSeatUI:useSeat(seat)
	if not self:isSeatInstalled(seat) then return end
	if self.vehicle:getCharacter(seat) then return end
	self:closeSelf()
	if self.character:getVehicle() then
		if self.vehicle:canSwitchSeat(self.vehicle:getSeat(self.character), seat) then
			if not ISVehicleMenu.moveItemsFromSeat(self.character, self.vehicle, seat, true, false) then return; end
			ISVehicleMenu.onSwitchSeat(self.character, seat)
		else
			-- In VanAmbulance, the front seats aren't reachable from the middle/rear.
			ISVehicleMenu.onExit(self.character)
			ISVehicleMenu.onEnter(self.character, self.vehicle, seat)
		end
	else
		ISVehicleMenu.onEnter(self.character, self.vehicle, seat)
	end
end

function ISVehicleSeatUI:exitSeat(seat)
	if not self:isSeatInstalled(seat) then return end
	local playerSeat = self.vehicle:getSeat(self.character)
	if playerSeat == -1 then return end
	self:closeSelf()
	if seat == playerSeat then
		ISVehicleMenu.onExit(self.character)
		return
	end
	if self.vehicle:isSeatOccupied(seat) then return end
	if self.character:getVehicle() then
		if self.vehicle:canSwitchSeat(playerSeat, seat) then
			ISVehicleMenu.onSwitchSeat(self.character, seat)
			ISVehicleMenu.onExit(self.character, seat)
		end
	end
end

function ISVehicleSeatUI:closeSelf()
	Events.OnCustomUIKeyPressed.Remove(ISVehicleSeatUI.OnKeyPressed)
	Events.OnCustomUIKeyReleased.Remove(ISVehicleSeatUI.OnKeyReleased)
	GameKeyboard.setDoLuaKeyPressed(true)
	self:removeFromUIManager()
	if JoypadState.players[self.playerNum+1] then
		setJoypadFocus(self.playerNum, nil)
	end
end

function ISVehicleSeatUI:onGainJoypadFocus(joypadData)
	ISPanelJoypad.onGainJoypadFocus(self, joypadData)
	self:setISButtonForB(self.close)
end

function ISVehicleSeatUI:onJoypadDown(button)
	ISPanelJoypad.onJoypadDown(self, button)
	if button == Joypad.AButton then
		self:useSeat(self.joypadSeat - 1)
	end
	if button == Joypad.BButton then
--		self:closeSelf()
	end
	if button == Joypad.XButton then
		self:exitSeat(self.joypadSeat - 1)
	end
end

function ISVehicleSeatUI:onJoypadDirUp()
	if not self.vehicle then return end
	local script = self.vehicle:getScript()
	if self.joypadSeat > 2 then
		self.joypadSeat = self.joypadSeat - 2
	end
end

function ISVehicleSeatUI:onJoypadDirDown()
	if not self.vehicle then return end
	local script = self.vehicle:getScript()
	if self.joypadSeat <= script:getPassengerCount() - 2 then
		self.joypadSeat = self.joypadSeat + 2
	end
end

function ISVehicleSeatUI:onJoypadDirLeft()
	if not self.vehicle then return end
	local script = self.vehicle:getScript()
	if self.joypadSeat % 2 == 0 then
		self.joypadSeat = self.joypadSeat - 1
	end
end

function ISVehicleSeatUI:onJoypadDirRight()
	if not self.vehicle then return end
	local script = self.vehicle:getScript()
	if self.joypadSeat % 2 == 1 and self.joypadSeat < script:getPassengerCount() then
		self.joypadSeat = self.joypadSeat + 1
	end
end

function ISVehicleSeatUI:setVehicle(vehicle)
	self.vehicle = vehicle
	self.mouseOverSeat = nil
	self.characterSeat = nil
	self.joypadSeat = 1
	if self.character:getVehicle() == vehicle then
		self.characterSeat = self.vehicle:getSeat(self.character)
		self.joypadSeat = self.characterSeat + 1
	end
	GameKeyboard.setDoLuaKeyPressed(false)
	Events.OnCustomUIKeyPressed.Add(ISVehicleSeatUI.OnKeyPressed)
	Events.OnCustomUIKeyReleased.Add(ISVehicleSeatUI.OnKeyReleased)
end

function ISVehicleSeatUI:centerOnScreen()
	local width = self:getWidth()
	local height = self:getHeight()
	local x = getPlayerScreenLeft(self.playerNum) + (getPlayerScreenWidth(self.playerNum) - width) / 2
	local y = getPlayerScreenTop(self.playerNum) + (getPlayerScreenHeight(self.playerNum) - height) / 2
	self:setX(x)
	self:setY(y)
end

function ISVehicleSeatUI:new(x, y, character)
	local playerNum = character:getPlayerNum()
	local width = 263
	local height = 600 - 100
	if y == 0 then
		y = getPlayerScreenTop(playerNum) + (getPlayerScreenHeight(playerNum) - height) / 2
	end
	if x == 0 then
		x = getPlayerScreenLeft(playerNum) + (getPlayerScreenWidth(playerNum) - width) / 2
	end
	local o = ISPanelJoypad:new(x, y, width, height)
	setmetatable(o, self)
	self.__index = self
	o.backgroundColor.a = 0.9
	o.character = character
	o.playerNum = playerNum
	return o
end

function ISVehicleSeatUI.OnKeyPressed(key)
	if not ISVehicleMenu.seatUI then return end
	local ui = ISVehicleMenu.seatUI[0]
	if not ui or not ui:isReallyVisible() then return; end
	if key == getCore():getKey("VehicleSwitchSeat") then
		ui:closeSelf()
		return
	end
	if key == Keyboard.KEY_ESCAPE then
		ui:closeSelf()
		GameKeyboard.eatKeyPress(key)
		return
	end
end

function ISVehicleSeatUI.OnKeyReleased(key)
	if not ISVehicleMenu.seatUI then return end
	local ui = ISVehicleMenu.seatUI[0]
	if not ui or not ui:isReallyVisible() then return; end
	if not ui.vehicle or not ui.vehicle:getScript() then return end
	local numSeats = ui.vehicle:getMaxPassengers()
	if key >= Keyboard.KEY_1 and key < Keyboard.KEY_1 + numSeats then
		if isKeyDown(Keyboard.KEY_LSHIFT) or isKeyDown(Keyboard.KEY_RSHIFT) then
			ui:exitSeat(key - Keyboard.KEY_1)
		else
			ui:useSeat(key - Keyboard.KEY_1)
		end
	end
end

