Town = {}

-- Local functions
local addToStock, handleMouseClick = nil, nil
local questCheckTimer = 0.0
local uiCreated = false
local sailOutButton, journalButton, mapButton

print("-- Town script start --")

-- Stock item definition
StockItem = { }
setmetatable(StockItem, { __index = StockItem; })
function StockItem:new(_item, _amount, _cost) return setmetatable({item = _item, amount = _amount or 0, cost = _cost or 0}, getmetatable(self)) end

-- Items in stock in towns
Town.stock = {{}, {}, {}, {}}


local PortCoordinates = {
  Vector2:new(686, 323),
  Vector2:new(693, 353),
  Vector2:new(150, 300)
}

local StoreCoordinates = {
  Vector2:new(913, 320),
  Vector2:new(0, 0), -- no store
  Vector2:new(790, 465)
}

local TavernCoordinates = {
  Vector2:new(270, 412),
  Vector2:new(118, 578),
  Vector2:new(262, 409)
}

local PortClickArea = {
  Rect:new(PortCoordinates[1].x - 35, PortCoordinates[1].y - 5, 70, 40),
  Rect:new(PortCoordinates[2].x - 35, PortCoordinates[2].y - 20, 70, 40),
  Rect:new(PortCoordinates[3].x - 35, PortCoordinates[3].y - 5, 70, 40),
}

local StoreClickArea = {
  Rect:new(StoreCoordinates[1].x - 28, StoreCoordinates[1].y - 30, 56, 36),
  Rect:new(StoreCoordinates[2].x - 41, StoreCoordinates[2].y - 30, 57, 36),
  Rect:new(StoreCoordinates[3].x - 28, StoreCoordinates[3].y - 30, 56, 36)
}

local TavernClickArea = {
  Rect:new(TavernCoordinates[1].x - 36, TavernCoordinates[1].y - 28, 72, 42),
  Rect:new(TavernCoordinates[2].x - 36, TavernCoordinates[2].y - 28, 72, 43),
  Rect:new(TavernCoordinates[3].x - 36, TavernCoordinates[3].y - 28, 72, 43)
}


local Location = { Port = {key = "town_location_harbour"}, Store = {key = "town_location_store"}, Tavern = {key = "town_location_tavern"} }
local leftMouseButtonDown, dragStartMousePosition, dragStartViewportPosition = false, nil, nil

function Town.getCurrentTownIndex ()
	return gTownState.getTownIndex()
end

function Town.goToSupplyStore  ()

	print("goToSupplyStore")

	local viewportRect = gViewport.getRect()
	local storeCoordinates = StoreCoordinates[Town.getCurrentTownIndex() + 1]
	local viewportCenterCoordinates = Vector2:new(gUtils.scale(storeCoordinates.x), gUtils.scale(storeCoordinates.y)) - Vector2:new(viewportRect.width / 2, viewportRect.height / 2)

	gViewport.animateMoveTo({
		x = viewportCenterCoordinates.x,
		y = viewportCenterCoordinates.y,
		id = gUtils.calculateHash("vportAnimStore")
	});

	Town.clearAllWindows()
end

function Town.clearAllWindows ()

	local rootWidget = LuaWidget(gGUI.getRootWidget(GameState.Town));

	if rootWidget == nil then
		return
	end

	gGUI.scheduleForDeletion(rootWidget.getWidgetWithID(gUtils.calculateHash("storeWnd")))
	gGUI.scheduleForDeletion(rootWidget.getWidgetWithID(gUtils.calculateHash("tavernWnd")))
	gGUI.scheduleForDeletion(rootWidget.getWidgetWithID(gUtils.calculateHash("shipwrightWnd")))
	gGUI.scheduleForDeletion(rootWidget.getWidgetWithID(gUtils.calculateHash("travelWnd")))
	gGUI.scheduleForDeletion(rootWidget.getWidgetWithID(gUtils.calculateHash("townchatWnd")))
	gGUI.scheduleForDeletion(rootWidget.getWidgetWithID(gUtils.calculateHash("hireWnd")))

	-- todo. replace with an actual journal object call
	-- gui.triggerButtonClickEvent(gUtils..calculateHash("closeJournal"));
end

function Town.showShipwright ()

  if QuestManager.questCompleted({id="returnsafely"}) == false then
    gGUI.showInfoMessage({key="no_shipwright_text"})
    return
  end

  gTownState.showShipwrightWindow()

end

function Town.showSupplyStoreWindow (contentType)
	gGUI.loadScriptedInterface("supplystore")
	UI.Interfaces["supplyStore"].create(contentType)
end

function Town.showTransactionWindow (contentType)


	if UI.Interfaces["supplyStoreTransaction"] == nil then

		local selectedStockItem = UI.Interfaces["supplyStore"].getSelectedStockItem()

		if selectedStockItem ~= nil then
			gGUI.loadScriptedInterface("buysellwindow")
			UI.Interfaces["supplyStoreTransaction"].create(contentType, selectedStockItem)
		else
			-- TODO. display a proper message
		end
	end
end

function Town.populateDialogList()

	print("populateTownDialogList")

	local chatWnd = LuaWidget(gGUI.getRootWidget(GameState.Town)).getWidgetWithID(gUtils.calculateHash("townchatWnd"))

	print(chatWnd)

	if chatWnd == nil then
		return
	end

	local listWidget = LuaList(LuaWidget(chatWnd).getWidgetWithID(gUtils.calculateHash("personsList")))
	local listDataSource = LuaListDataSource(listWidget.getDataSource())
	local currentTownIndex = Town.getCurrentTownIndex() + 1
	local unopenedTopicIcon = gSpriteManager.getSprite(3, SpriteGroup.DialogScreen)
	local openedTopicIcon = gSpriteManager.getSprite(4, SpriteGroup.DialogScreen)
	local characters = DialogManager.listAllAvailableDialogs()

	listDataSource.removeAllItems()

	-- Add all characters to list
	for i = 1, #characters do
		listDataSource.addItem({
			text 			= DialogManager.Dialogs[characters[i]].getName(),
			str1 			= characters[i],
			accessoryType 	= ListRowAccessory.DisclosureDark,
			icon 			= __ternary(DialogManager.newDialogTopicsAvailable(characters[i]), unopenedTopicIcon, openedTopicIcon)
		})
	end

end


-- Local helper function
addToStock = function(townIndex, stockItem)
	table.insert( Town.stock[townIndex], stockItem )	-- Push to back
end

function Town.populateStock ()

	-- Return Safely quest completed and goods are being transported again
	local goodsTransportationRestored = QuestManager.questCompleted({id = "returnsafely"})

	print("goodsTransportationRestored", goodsTransportationRestored)

	Town.stock[Towns.Marciudad] = {}

	for i=1,3 do

		--[[
			---------------------------------------------------------------------------------------------------------------------------------------------------
									Item									Amount															Cost
			---------------------------------------------------------------------------------------------------------------------------------------------------
		]]--

		addToStock(i, StockItem:new(ItemDefinitions.Tent, 					__ternary(goodsTransportationRestored, math.random(0, 3), 1), 	math.random(190, 220)))
		addToStock(i, StockItem:new(ItemDefinitions.Axe,					__ternary(goodsTransportationRestored, math.random(0, 4), 2),	math.random(45, 54)))
		addToStock(i, StockItem:new(ItemDefinitions.Machete,				__ternary(goodsTransportationRestored, math.random(0, 2), 0),	math.random(100, 120)))
		addToStock(i, StockItem:new(ItemDefinitions.Flint,					__ternary(goodsTransportationRestored, math.random(1, 5), 2),	math.random(22, 30)))
		addToStock(i, StockItem:new(ItemDefinitions.FishingRod,				__ternary(goodsTransportationRestored, math.random(0, 2), 1),	math.random(70, 80)))
		addToStock(i, StockItem:new(ItemDefinitions.Saw,					__ternary(goodsTransportationRestored, math.random(0, 2), 0),	math.random(95, 108)))
		addToStock(i, StockItem:new(ItemDefinitions.Shovel,					__ternary(goodsTransportationRestored, math.random(0, 3), 1),	math.random(70, 80)))
		addToStock(i, StockItem:new(ItemDefinitions.Pickaxe,				__ternary(goodsTransportationRestored, math.random(0, 2), 0),	math.random(70, 80)))
		addToStock(i, StockItem:new(ItemDefinitions.Binoculars,				__ternary(goodsTransportationRestored, math.random(0, 1), 1),	math.random(475, 550)))
		addToStock(i, StockItem:new(ItemDefinitions.Flask,					__ternary(goodsTransportationRestored, math.random(0, 6), 2),	math.random(9, 11)))

		addToStock(i, StockItem:new(ItemDefinitions.Knife,					__ternary(goodsTransportationRestored, math.random(0, 6), 1),	math.random(25, 32)))
		addToStock(i, StockItem:new(ItemDefinitions.Sword,					__ternary(goodsTransportationRestored, math.random(0, 4), 1),	math.random(140, 155)))
		addToStock(i, StockItem:new(ItemDefinitions.Bow,					__ternary(goodsTransportationRestored, math.random(0, 3), 1),	math.random(45, 55)))
		addToStock(i, StockItem:new(ItemDefinitions.Crossbow,				__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(275, 312)))
		addToStock(i, StockItem:new(ItemDefinitions.Musket,					__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(1400, 1600)))
		addToStock(i, StockItem:new(ItemDefinitions.GreatSword,				__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(490, 520)))
		addToStock(i, StockItem:new(ItemDefinitions.Mace,					__ternary(goodsTransportationRestored, math.random(0, 4), 1),	math.random(390, 415)))
		addToStock(i, StockItem:new(ItemDefinitions.Spear,					__ternary(goodsTransportationRestored, math.random(0, 5), 1),	math.random(140, 160)))
		addToStock(i, StockItem:new(ItemDefinitions.Halberd,				__ternary(goodsTransportationRestored, math.random(0, 3), 0),	math.random(285, 320)))
		addToStock(i, StockItem:new(ItemDefinitions.Dagger,					__ternary(goodsTransportationRestored, math.random(0, 8), 0),	math.random(45, 55)))
		addToStock(i, StockItem:new(ItemDefinitions.BattleAxe,				__ternary(goodsTransportationRestored, math.random(0, 1), 1),	math.random(440, 465)))

		addToStock(i, StockItem:new(ItemDefinitions.ArmorLeather,			__ternary(goodsTransportationRestored, math.random(0, 3), 1),	math.random(115, 130)))
		addToStock(i, StockItem:new(ItemDefinitions.ArmorScale,				__ternary(goodsTransportationRestored, math.random(0, 2), 0),	math.random(170, 185)))
		addToStock(i, StockItem:new(ItemDefinitions.ArmorBrigandine,		__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(235, 260)))
		addToStock(i, StockItem:new(ItemDefinitions.ArmorCoatOfPlates,		__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(305, 335)))
		addToStock(i, StockItem:new(ItemDefinitions.ArmorMail,				__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(290, 310)))
		addToStock(i, StockItem:new(ItemDefinitions.ArmorSplinted,			__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(385, 415)))
		addToStock(i, StockItem:new(ItemDefinitions.ArmorPlate,				__ternary(goodsTransportationRestored, math.random(0, 1), 0),	math.random(485, 525)))

		addToStock(i, StockItem:new(ItemDefinitions.Tobacco,				__ternary(goodsTransportationRestored, math.random(0, 10), 0),	math.random(13, 18)))
		addToStock(i, StockItem:new(ItemDefinitions.FreshWater,				9999,															0.0))
		addToStock(i, StockItem:new(ItemDefinitions.DriedMeat,				9999,															0.4))
		addToStock(i, StockItem:new(ItemDefinitions.Biscuits,				9999,															0.6))
		addToStock(i, StockItem:new(ItemDefinitions.Bread,					9999,															0.5))

	end

end

--[[

void Town..addSupply(int itemType, int count)
{
  ITEM_DEF itemDef = ItemDefs[itemType];
  SItem * item = 0;

  if (itemDef.category & ITEM_CAT_CONSUMABLE)
  {
    SItem * item = getSupplies(currentTownIndex)->getItemOfType((INV_TYPE_DEF)itemType);

    // Don't have this item yet
    if (!item)
    {
      item = Inventory..createItem(itemType, 0, 0, (double)count);
      getSupplies(currentTownIndex)->addItem( item );
    }
    else
    {
      item->param3 += count;
    }
  }
  else
  {
    for (int i = 0; i < count; ++i)
    {
      item = Inventory..createItem(itemType);
      getSupplies(currentTownIndex)->addItem( item );
    }
  }

  return;
}

--]]

function Town.addSupply(itemDefinition, amount)

	local playerSupplies = LuaInventory(gTownState.getSupplies(Town.getCurrentTownIndex()));

	-- Single instance of item but with variable amount
	if itemDefinition:category(ItemCategory.Consumable) == true then

		local itemUserdata = playerSupplies.getItemOfType({primary = itemDefinition.index})

		-- Create item if not listed in supplies
		if itemUserdata == nil then
			print("new item needs to be created")
			playerSupplies.addItem(gUtils.createInventoryItem({primary = itemDefinition.index, amount = amount}))

		-- If it exists just increase its amount
		else
			local item = LuaInventoryItem(itemUserdata)
			item.param3(item.param3() + amount)
			print(item.param3())
		end

	-- Each item is a separate instance
	else
		for i=1, amount do
			playerSupplies.addItem(gUtils.createInventoryItem({primary = itemDefinition.index}))
		end
	end

end

function Town.openDocksWindow()
	gGUI.loadScriptedInterface("docks")
	UI.Interfaces["docks"].create()
end


function Town.sailOut ()

  print("Sail out!")

  local vesselCount = gParty.getVesselCount()

  if vesselCount == 0 then
    gGUI.showInfoMessage({ key = "sailing_out_no_ships" })
    return

  elseif vesselCount >= 1 then

    for i=0,vesselCount-1 do
      local vessel = LuaShip(gParty.getVessel(i))
      if vessel.checkStateFlag(Ship.Built) == true then
        gGUI.showInfoMessage({ key = "sailing_out_ship_under_construction" })
        return
      end
    end

  end

  if gGame.getSeason() == Season.Winter then
    gGUI.showInfoMessage({ key = "sailing_out_winter" })
    return
  end

  for i=0,gParty.getMemberCount()-1 do
    local player = LuaPlayer(gParty.getPlayer(i))
    if player.isOnShip() == false then
      gGUI.showInfoMessage({ key = "sailing_out_unassigned_members" })
      return
    end
  end

  if gVarStore.getBool("barlow_hired") == true then

    print("Barlow's travel window")

    if UI.Interfaces["sailout"] == nil then
  	 gGUI.loadScriptedInterface("sailout", true)
    end

    return
  else
    gGUI.doScreenTransition({id = ConstSailOutOfTownTransition, delay = 0.1})
  end

  print("All is fine")





end

function Town.passSeason()

	print("passSeason")

	if 	QuestManager.questAccepted({id = "spicerun"}) == true and
		  (Town.getCurrentTownIndex() + 1) == Towns.Marciudad and
		  gVarStore.getBool("barlow_hired") == false and
		  gVarStore.getBool("barlow_in_town") == true
	then
    gGUI.showInfoMessage({ key = "pass_season_cancel_barlow" });
    return
	end

  gGUI.doScreenTransition({id = 3})

end


--
-- Game state methods
--

function Town.onInit (initParam)

	print("Town.onInit", initParam)

	-- First init (after intro & tutorial)
	if initParam == -2 then

    QuestManager.sourceAvailable({id = "general", value = true})
    QuestManager.questAccepted({id = "gettingstarted", value = true})

		--Town.populateStock()
	end


  if uiCreated == false then

    uiCreated = true

    local screenSize = gGUI.getScreenSize()

    mapButton = LuaButton(gGUI.createButton({
      width = 64,
      height = 64,
      y = gUtils.unscale(screenSize.y) - 66,
      image = gSpriteManager.getSprite(16, SpriteGroup.Town),
      id = 139,
      visible = false
    }))

    journalButton = LuaButton(gGUI.createButton({
      width = 64,
      height = 64,
      y = gUtils.unscale(screenSize.y) - 66,
      image = gSpriteManager.getSprite(17, SpriteGroup.Town),
      id = 140,
      visible = false
    }))

    sailOutButton = LuaButton(gGUI.createButton({
      width = 64,
      height = 64,
      y = gUtils.unscale(screenSize.y) - 66,
      image = gSpriteManager.getSprite(15, SpriteGroup.Town),
      visible = false
    }))

    sailOutButton:onClick(Town.sailOut)

  end



end

-- Called on every frame (if game window has focus)
function Town.onUpdate (frameTime)

  if gGame.getState() ~= GameState.Town then
  	return
  end

  questCheckTimer = questCheckTimer + frameTime

  if questCheckTimer >= 3.0 then
    questCheckTimer = 0.0
    QuestManager.checkActiveQuests()
  end


  if gGUI.isStoryTextShown() == true then
    mapButton.setIsVisible(false)
    journalButton.setIsVisible(false)
    sailOutButton.setIsVisible(false)
  else
    mapButton.setIsVisible(true)
    journalButton.setIsVisible(true)
    local numberOfActionButtons = 2
    if sailOutButton ~= nil then
      sailOutButton.setIsVisible(false)
      if gParty.getVesselCount() > 0 then
        sailOutButton.setIsVisible(true)
        numberOfActionButtons = numberOfActionButtons + 1
      end
    end
    local screenSize = gGUI.getScreenSize()
    local buttonX = (gUtils.unscale(screenSize.x) / 2) - ((46 * numberOfActionButtons) / 2)
    mapButton.setX(buttonX)
    journalButton.setX(buttonX+46)
    if numberOfActionButtons == 3 then
      sailOutButton.setX(buttonX+92)
    end
  end
end

-- Called every frame regardless of game window focus
function Town.onDraw ()

end




--
-- Delegates
--

function Town.onEventGUI (args)

	local widget = LuaWidget(args.source)
	local parentWidget = nil

	if widget.instance() ~= nil then
		parentWidget = LuaWidget(widget.getParent())
	end

	if args.type == EventGUI.ButtonClicked then

	elseif args.type == EventGUI.ListItemSelected then

		local listWidget = LuaList(widget.instance())

		if widget.getID() == gUtils.calculateHash("locActions") then

			local listDataSource = LuaListDataSource(listWidget.getDataSource())
			local listItem = LuaListDataItem(listDataSource.getItemAtIndex(listWidget.getSelectedRow()))
			local listItemKey = listItem.str1()


			if listItemKey == "buy" then
				Town.populateStock() -- temp
				Town.showSupplyStoreWindow("buy")

			elseif listItemKey == "sell" then
				Town.showSupplyStoreWindow("sell")

			elseif listItemKey == "party" then
				gTownState.showPartyWindow()

			elseif listItemKey == "hire" then
				gTownState.showHireWindow()

			elseif listItemKey == "talk" then
				gTownState.showTownChatWindow()

			elseif listItemKey == "seasonpass" then
				Town.passSeason()

			elseif listItemKey == "docks" then
				gTownState.showDocksWindow()

      elseif listItemKey == "shipwright" then
        Town.showShipwright()

      elseif listItemKey == "travel" then
        gTownState.showScheduleAndCharterWindow()
      end

			gWorld.clearPinnedWidgets()
		end
	end

	return true
end

function Town.onEventSystem (args)
	if gGame.getState() ~= GameState.Town then
		return true
	end

	--[[for k, v in pairs(args) do
		print("  # "..k.." = ", v)
	end]]--

	if args.type == EventSystem.MouseButtonPressed then
		leftMouseButtonDown = true
		dragStartMousePosition = Vector2:new(args.mouseButton.x, args.mouseButton.y)
		--print("mouse:", args.mouseButton.x, args.mouseButton.y)
		dragStartViewportPosition = gViewport.getPosition()
	elseif args.type == EventSystem.MouseButtonReleased and dragStartMousePosition ~= nil then
		leftMouseButtonDown = false
		local dx = dragStartMousePosition.x - args.mouseButton.x
		local dy = dragStartMousePosition.y - args.mouseButton.y

		--print("delta: ", dx, dy)

		if math.abs(dx) < gUtils.scale(4) and math.abs(dy) < gUtils.scale(4) then
			if handleMouseClick(args) then
        return false
      end
		else
      return false
    end
	elseif args.type == EventSystem.MouseMoved then
		if dragStartMousePosition ~= nil and leftMouseButtonDown == true and (gGame.isMouseButtonPressed(MouseButton.Left) or gGame.isMouseButtonPressed(MouseButton.Right)) then
			local dx = dragStartMousePosition.x - args.mouseMove.x;
			local dy = dragStartMousePosition.y - args.mouseMove.y;
			if math.abs(dx) >= gUtils.scale(4) or math.abs(dy) >= gUtils.scale(4) then
				gViewport.setPosition(Vector2:new( dragStartViewportPosition.x + dx, dragStartViewportPosition.y + dy))
			end
		else
      leftMouseButtonDown = false
      dragStartMousePosition = nil
    end
	elseif args.type == EventSystem.MouseLeft then
		leftMouseButtonDown = false
	end

	return true
end

function Town.onViewportAnimationComplete (args)

	if args.id == gUtils.calculateHash("vportAnimStore") then
		print("store viewport animation complete")
		Town.populateStock()
		Town.showSupplyStoreWindow("buy")
	end

	return false
end

function Town.showLocationOptions (location)

  if location == Location.Store then

    if gTownState.isLocationAvailable(TownLocation.Store) == false then
      return
    end

  	if Town.getCurrentTownIndex() + 1 == Towns.Oldden and QuestManager.questCompleted({id = "returnsafely"}) == false then

  		-- Mark that we have visited the supply store
  		-- Next time when conversing with the tavernkeeper we show an option to ask about the store
  	  gVarStore.setBool("start_supplystore_visited", true)

  		gGUI.showMessageBox({
  			title = gUtils.translate("supply_store_initial_closed_title"),
  			text = gUtils.translate("supply_store_initial_closed_msg"),
  		})

  		return

  	end

  end

	local wnd = LuaWindow(gGUI.createWindow({
		width = 100,
		height = 150,
		title = "%"..location.key,
		noParent = true,
		flags = 0
	}));

	local listDataSource = LuaListDataSource(gGUI.createListDataSource())

	print(listDataSource)

	if location == Location.Store then

		listDataSource.addItem({key = "town_buy_goods", str1 = "buy"})
		listDataSource.addItem({key = "town_sell_goods", str1 = "sell"})
		-- listDataSource.addItem({text = "Trade", str1 = "trade"})

	elseif location == Location.Tavern then

		listDataSource.addItem({key = "town_manage_party", str1 = "party"})

    if gVarStore.getBool("accomodation_available") == true then
	    listDataSource.addItem({key = "town_pass_season", str1 = "seasonpass"})
    end

    if gVarStore.getBool("asked_about_hiring") == true then
      listDataSource.addItem({key = "town_hire_adventurers", str1 = "hire"})
    end

		listDataSource.addItem({key = "town_talk_to_folk", str1 = "talk"})

	elseif location == Location.Port then

		listDataSource.addItem({key = "town_visit_docks", str1 = "docks"})

		if gVarStore.getBool("travel_available") == true then
      listDataSource.addItem({key = "town_travel_schedules", str1 = "travel"})
    end

    if Town.getCurrentTownIndex()+1 == Towns.Reval then
      listDataSource.addItem({key = "town_shipwright", str1 = "shipwright"})
    end

	end


	local optionsList = LuaList(gGUI.createList({
		parent = wnd.instance(),
		id = "locActions",
		x = 6,
		y = 18,
		visibleRows = listDataSource.countItems(),
		fontIndex = 0,
		rowHeight = 12,
		dataSource = listDataSource.instance(),
		showSelection = false
	}))

	local listBounds = optionsList.fitToContent()

	print("listBounds", listBounds)

	optionsList.setWidth(listBounds.x + 10)
	optionsList.setHeight(listBounds.y)
	wnd.setWidth(listBounds.x + 12 + 10)
	wnd.setHeight(listBounds.y + 25)

  local arrowDown = LuaImage(gGUI.createImage({
    parent = wnd.instance(),
    x = wnd.getWidth() / 2 - 6,
    y = wnd.getHeight() - 4,
    sprite = gSpriteManager.getSprite(149, SpriteGroup.GUI)
  }))

	local position = nil;
	local townIndex = Town.getCurrentTownIndex() + 1

	if location == Location.Port then
		position = Vector2:new(PortCoordinates[townIndex].x, PortCoordinates[townIndex].y - 8)
	elseif location == Location.Tavern then
		position = Vector2:new(TavernCoordinates[townIndex].x, TavernCoordinates[townIndex].y - 34)
	elseif location == Location.Store then
		position = Vector2:new(StoreCoordinates[townIndex].x, StoreCoordinates[townIndex].y - 29)
	end

	if position == nil then
		print("Position is nil in Town.showLocationOptions ...")
		return
	end

	gWorld.pinWidgetToPosition({widget = wnd.instance(), x = position.x, y = position.y, origin = Origin.BottomCenter})

end

handleMouseClick = function(args)
	-- print("click")
	if args.mouseButton.button == MouseButton.Left then
		local viewportPosition = gViewport.getPosition()
		local mwc = Vector2:new(gUtils.unscale(args.mouseButton.x + viewportPosition.x), gUtils.unscale(args.mouseButton.y + viewportPosition.y)) -- Mouse World Coordinates

		print(mwc.x, mwc.y)

    gWorld.clearPinnedWidgets()

		if PortClickArea[Town.getCurrentTownIndex() + 1]:containsPoint(mwc) then
			Town.showLocationOptions(Location.Port)
      return true
		elseif StoreClickArea[Town.getCurrentTownIndex() + 1]:containsPoint(mwc) then
			Town.showLocationOptions(Location.Store)
      return true
		elseif TavernClickArea[Town.getCurrentTownIndex() + 1]:containsPoint(mwc) then
			--print("show tavern")
			Town.showLocationOptions(Location.Tavern)
      return true
		else
			--print("no click area")
		end
	end
  return false
end




-- local flags = bit32.lshift(1, 0) + bit32.lshift(1, 1)
-- print("bittest. ", flags)

-- gLuaHandler.registerDelegateCallbacks(Town, Delegates.EventsGUI, 9, Town.onEventGUI)
-- gLuaHandler.registerDelegateCallbacks(Town, Delegates.EventsSystem, 0, Town.onEventSystem)
gLuaHandler.registerDelegateCallbacks(Town, Delegates.ViewportAnimation, 0, Town.onViewportAnimationComplete)

print("-- Town script end --")
