enableSound = true --this enables or disables sound.  For the options menu
isCurrentButtonElement = false --this checks whether the currently highlighted button is an element icon, so EDF info can appear.
currentSelectedResource = false --this defines the currently selected resource
local wasCurrentBrowserShowing = false
local root = getRootElement()
local thisResourceRoot = getResourceRootElement(getThisResource())
local bar = {}
--These tables define the buttons that go on the top.  the names match their filename.
menuButtons = { { ["name"]="new" },{ ["name"]="open" },{ ["name"]="save" },{ ["name"]="save as" },{ ["name"]="options" },{ ["name"]="undo" },{ ["name"]="redo" }, { ["name"]="locations" }--[[,{ ["name"]="clipboard" },{ ["name"]="exit" } ]]}
secondMenuButtons = { { ["name"]="current elements" },{ ["name"]="map settings" },{["name"]="definitions"}, { ["name"]="test" } }

resourceElementDefinitions = {} --This table stores all edf definitions of every element type accroding to resource.
iconData = {} --iconData allows differentiation between different icon types, and stores the function for each icon.
elementIcons = {} --these are the icons that go along the bottom

local iconPath = "client/images/"
local defaultElementDefinition = "editor_main"
screenX, screenY = guiGetScreenSize() --this gets the local screen size to work out gui
guiConfig = {
	iconSize = 48, --this is the default icon size (width and height)
	topMenuAlign = "center",
	elementIconsAlign = "left"
}
local guiShowing = true --this is a variable used to detect if gui is hidden or shown.
local currentHUDAlpha
local requireBinds

function table.size(tab)
    local length = 0
    for _ in pairs(tab) do length = length + 1 end
    return length
end

function startGUI(resource)
	outputConsole("GUI load time measures (ms):")
	TIME = getTickCount()
	createWorldDetector()
	---Create the other menus before creating the layout
	outputConsole("createWorldDetector() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createCurrentBrowser()
	outputConsole("createCurrentBrowser() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createOptionsDialog()
	outputConsole("createOptionsDialog() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createLocationsMenu()
	outputConsole("createLocationsMenu() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createBrowser()
	outputConsole("createBrowser() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createMapSettings()
	outputConsole("createMapSettings() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createDefinitionsDialog()
	outputConsole("createDefinitionsDialog() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createLoadDialog()
	outputConsole("createLoadDialog() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createSaveDialog()
	outputConsole("createSaveDialog() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	--create all the icons
	createGUILayout()
	outputConsole("createGUILayout() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createTestDialog()
	outputConsole("createTestDialog() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	createPropertiesBox()
	outputConsole("createPropertiesBox() : "..tostring(getTickCount()-TIME)); TIME = getTickCount()
	isGUICreated = true
	triggerServerEvent ( "onClientGUILoaded", getLocalPlayer() )
	welcomeUser()
	setHUDAlpha(0.2)
end
addEventHandler("onClientResourceStart",thisResourceRoot, startGUI )

function scrollEDF(key,keyState)
	if isCurrentButtonElement == false then return end
	if key == "edf_prev" then prevEDF()
	elseif key == "edf_next" then nextEDF()
	end
end

--these funcs are server side, so i port them to client in me_gui_server and these funcs
addEvent ( "doLoadEDF",true )
addEvent ( "doUnloadEDF",true )

function onEDFResourceStart(resource)
	if resourceElementDefinitions[getResourceName(resource)] then
		refreshElementIcons()
	end
end
addEventHandler ( "onClientResourceStart", getRootElement(), onEDFResourceStart )

function createElementIcons ( tableEDF, resource )
	--store all our data neatly under the resource
	local defTable = clearNonCreatableElements ( tableEDF["elements"] )
	if table.size(defTable) > 0 then
		resourceElementDefinitions[resource] = defTable
		refreshElementIcons()
	end
end
addEventHandler ( "doLoadEDF", root, createElementIcons )


-----------------------------------------------
function destroyElementIcons ( resource )
	resourceElementDefinitions[resource] = nil
	if resource == currentSelectedResource then
		nextEDF()
	end
	refreshElementIcons()
end
addEventHandler ( "doUnloadEDF", root, destroyElementIcons )

edfResourcesNext = {}
	
function refreshElementIcons()
	currentBrowser.update()
	currentBrowserGUI.dropdown:setValue(1)
	for icon, Table in pairs(elementIcons) do --remove any old icons
		guiSetVisible ( icon, false )
		--destroyElement ( Table["button"] )
		destroyElement ( icon )
		elementIcons[icon] = nil
		iconData[icon] = nil
	end
	--
	edfResourcesNext = {}
	elementIcons = {}
	local nameTable = {} --this is used to ensure any elements with the same name have a varied label
	for resource,tableElements in pairs(resourceElementDefinitions) do
		if currentSelectedResource == false then
			currentSelectedResource = resource
			if ( currentSelectedResource == defaultElementDefinition ) then 
				setSelectedResourceText ( "DEFAULT" )
			else
				setSelectedResourceText ( string.upper(currentSelectedResource) )
			end
		end
		local tableSize = #edfResourcesNext
		if ( not tableSize ) then tableSize = 0 end
		nextKey = tableSize + 1
		--make this table into an array so its sorted nicely
		edfResourcesNext[resource] = {}
		--
		--work out the offset for positioning
		local menuButtonsOffset
		if guiConfig.elementIconsAlign == "right" or guiConfig.elementIconsAlign == "center" then
			--count the number of elements
			local totalElements = 0
			for k,v in pairs(tableElements) do
				totalElements = totalElements + 1
			end
			if guiConfig.elementIconsAlign == "right" then
				menuButtonsOffset = screenX - (guiConfig.iconSize * totalElements)
			else
				menuButtonsOffset = ( screenX - (guiConfig.iconSize * totalElements))/2 --this works out where to start creating the top menu's gui, so it's centred.
			end
		else
			menuButtonsOffset = 0
		end
		local k = 0
		local sortingFunction = function(A, B)
			return tableElements[A]["friendlyname"] < tableElements[B]["friendlyname"]
		end
		for elementName,dataTable in orderedPairs(tableElements, sortingFunction) do
			--edf will have to pass a image straight to me_gui. therefore this check to see if an icon is false will have to make a generic icon rather than dir.
			local iconDir = dataTable["icon"]
			local friendlyName = dataTable["friendlyname"]
			if friendlyName == nil then friendlyName = elementName end
			local theIcon
			local posX = ((k)*guiConfig.iconSize) + menuButtonsOffset
			if not iconDir then --if edf never passed an icon
				--create a generic one
				theIcon = guiCreateStaticImage ( posX, screenY - guiConfig.iconSize, guiConfig.iconSize, guiConfig.iconSize, iconPath.."elementmenu/generic.png", false) --, getResourceFromName(key)) 
			else
				--otherwise create edf's icon
				if (getResourceFromName(resource)) then -- To prevent debug when trying to load from a not yet started resource
					theIcon = guiCreateStaticImage ( posX, screenY - guiConfig.iconSize, guiConfig.iconSize, guiConfig.iconSize, ":"..resource.."/"..iconDir, false)
				end
			end
			if not theIcon then
				--if edf's icon was not made successfully, then create a generic one.
				theIcon = guiCreateStaticImage ( posX, screenY - guiConfig.iconSize, guiConfig.iconSize, guiConfig.iconSize, iconPath.."elementmenu/generic.png", false) 
			end
			addEventHandler ( "onClientGUIMouseDown", theIcon, buttonClicked, false )
			
			--store the icon type, and the function action of the button
			iconData[theIcon] = {}
			iconData[theIcon]["type"] = "elementIcons"
			iconData[theIcon]["clicked"] = elementIcons_Clicked
			iconData[theIcon]["mouseOver"] = elementIconsMouseOver
			
			--store this under the element icons table
			elementIcons[theIcon] = {}
			elementIcons[theIcon]["name"] = friendlyName
			elementIcons[theIcon]["elementName"] = elementName
			elementIcons[theIcon]["resource"] = resource
			
		
			--check if any other elements used the name
			if nameTable[elementName] ~= nil then
				--since we found another element with the same name, set the old name to element [resource]
				local oldIcon = nameTable[elementName]["icon"]
				local oldFriendlyName = nameTable[elementName]["friendlyName"]
				local oldResource = nameTable[elementName]["resource"]
				elementIcons[oldIcon]["labelName"] = oldFriendlyName.." ["..oldResource.."]"
				--set the current one with name [resource] too.
				elementIcons[theIcon]["labelName"] = friendlyName.." ["..resource.."]"
			end	
			
			nameTable[elementName] = {}
			nameTable[elementName]["resource"] = resource
			nameTable[elementName]["friendlyName"] = friendlyName
			nameTable[elementName]["icon"] = theIcon

			table.insert ( edfResourcesNext[resource], theIcon )
			--hide any non selected icons
			if ( resource ~= currentSelectedResource ) or ( not guiShowing ) then
				guiSetVisible ( theIcon, false )
			end
			k = k + 1
		end
	end
	--we move the selected highlighter to the front, so that it appears above the new GUI
	if ( selected ) then
		guiMoveToBack ( selected )
		guiSetVisible ( selected, false )
	end
	setHUDAlpha(currentHUDAlpha)
	if getElementData ( localPlayer, "waitingToStart" ) then
		setGUIShowing(false)
	end
end
	
function createGUILayout()
	---create all of our top menu
	local gap = guiConfig.iconSize/2 --this calculates the gap in between the topMenu and the secondTopMenu
	local menuButtonsOffset
	if guiConfig.topMenuAlign == "left" then
		menuButtonsOffset = 0
	elseif guiConfig.topMenuAlign == "right" then
		menuButtonsOffset = screenX - ((guiConfig.iconSize * #menuButtons) + gap + (guiConfig.iconSize * #secondMenuButtons))
	else
		menuButtonsOffset = ( screenX - ( (guiConfig.iconSize * #menuButtons) + gap + (guiConfig.iconSize * #secondMenuButtons) ) )/2 --this works out where to start creating the top menu's gui, so it's centred.
	end
	
	local x
	for k,v in pairs(menuButtons) do --centre our top menu buttons
		local name = v["name"]
		x = ((k-1)*guiConfig.iconSize) + menuButtonsOffset
		local pathName = string.gsub(name, " ", "_" )
		v["icon"] = guiCreateStaticImage ( x, 0, guiConfig.iconSize, guiConfig.iconSize, iconPath.."topmenu/"..pathName..".png", false )
		
		iconData[v["icon"]] = {}
		iconData[v["icon"]]["type"] = "menuButtons"
		iconData[v["icon"]]["name"] = name --for highlighting.lua
		iconData[v["icon"]]["clicked"] = topMenuClicked[name]
		iconData[v["icon"]]["mouseOver"] = topMenuMouseOver
		
		addEventHandler ( "onClientGUIMouseDown", v["icon"], buttonClicked, false )
	end
	for k,v in pairs(secondMenuButtons) do --centre our top menu buttons
		local name = v["name"]
		local pathName = string.gsub(name, " ", "_" )
		v["icon"] = guiCreateStaticImage ( ((k-1)*guiConfig.iconSize) + x + guiConfig.iconSize + gap, 0, guiConfig.iconSize, guiConfig.iconSize, iconPath.."topmenu/second/"..pathName..".png", false )
		iconData[v["icon"]] = {}
		iconData[v["icon"]]["type"] = "secondMenuButtons"
		iconData[v["icon"]]["name"] = name --for highlighting.lua
		iconData[v["icon"]]["clicked"] = topMenuClicked[name]
		iconData[v["icon"]]["mouseOver"] = topMenuMouseOver
		
		addEventHandler ( "onClientGUIMouseDown", v["icon"], buttonClicked, false )
	end
	
	--create our highlighters
	selected = guiCreateStaticImage ( 0, 0, guiConfig.iconSize, guiConfig.iconSize, iconPath.."select.png", false )
	selectedShadow =  guiCreateLabel ( 0, 0, screenX, 16, "", false )
	selectedText =  guiCreateLabel ( 0, 0, screenX, 16, "", false )
	
	local resourceX = ( 5/960 * screenX )
	local resourceY = ( screenY - 85 )
	selectedResourceShadow =  guiCreateLabel ( resourceX, resourceY, screenX, 16, "", false )
	selectedResourceText =  guiCreateLabel ( resourceX + 1, resourceY + 1, screenX, 16, "", false )
	
	guiLabelSetColor ( selectedResourceText, 200, 25, 25 )
	guiLabelSetColor ( selectedText, 255, 255, 255 )
	guiLabelSetColor ( selectedResourceShadow, 0, 0, 0 )
	guiLabelSetColor ( selectedShadow, 0, 0, 0 )
	
	guiSetVisible ( selected, false )
	setHUDAlpha(currentHUDAlpha)
	if getElementData ( localPlayer, "waitingToStart" ) then
		setGUIShowing(false)
	end
end

function toggleHUDShowing(k1,k2,state)
	setGUIShowing(not guiShowing)
	showPlayerHudComponent("radar", guiShowing)
	showChat ( guiShowing )
end

function setGUIShowing(state)
	for icon,data in pairs(iconData) do
		if data.type == "elementIcons" and state then
			if elementIcons[icon]["resource"] == currentSelectedResource then
				guiSetVisible ( icon,true )
			end
		else
			guiSetVisible ( icon, state )
		end
	end
	currentButton = false
	if state == false then 
		guiSetVisible ( selected, false ) 
		setSelectedText ( 0.5, 0.5, "" )
		if guiGetVisible(currentBrowserGUI.browser) then
			wasCurrentBrowserShowing = true
		else wasCurrentBrowserShowing = false end
		closeCurrentBrowser()
	else
		if wasCurrentBrowserShowing then
			showCurrentBrowser ( false,false,false,false,false,true )
		end
	end
	guiSetVisible(selectedResourceText, state )
	guiSetVisible(selectedResourceShadow, state )
	guiShowing = state
	isCurrentButtonElement = false
end

function setHUDAlpha(level)
	if not level then return false end
	local isFalse
	for icon,data in pairs(iconData) do
		returnValue = guiSetAlpha ( icon, level )
		if not returnValue then isFalse = true end
	end
	guiSetAlpha ( selected, level ) 
	guiSetAlpha(selectedResourceText, level )
	guiSetAlpha(selectedResourceShadow, level )
	currentHUDAlpha = level
	return not isFalse
end

addEvent "onFreecamMode"
addEvent "onCursorMode"

addEventHandler ( "onFreecamMode", root, function() setHUDAlpha(0.2) hideHighlighter() end )
addEventHandler ( "onCursorMode", root, function() setHUDAlpha(1) end )

function destroyAllIconGUI()
	for icon,data in pairs(iconData) do
		guiSetVisible ( icon, false )
		destroyElement ( icon )
	end
	currentButton = false
	guiSetVisible ( selected, false ) 
	destroyElement ( selected )
	setSelectedText ( 0.5, 0.5, "" )
	destroyElement ( selectedText )
	destroyElement ( selectedShadow )
	guiSetVisible(selectedResourceText, false )
	guiSetVisible(selectedResourceShadow, false )
	destroyElement ( selectedResourceText )
	destroyElement ( selectedResourceShadow )
	iconData = {}
	elementIcons = {}
	isCurrentButtonElement = false
	currentSelectedResource = false
end

local mta_playSoundFrontEnd = playSoundFrontEnd
function playSoundFrontEnd ( sound )
	if enableSound == false then return false end
	returnValue  = mta_playSoundFrontEnd ( sound )
	return returnValue
end

function guiShowMessageBox ( message, boxType, title, forced, button1, button2, button3 )
	playSoundFrontEnd ( 5 )
	local a1,a2,a3 = msgbox.guiShowMessageBox ( message, boxType, title, forced, button1, button2, button3 )
	return a1,a2,a3
end

function clearNonCreatableElements(elementTable)
	for elementName,data in pairs(elementTable) do
		if not data.createable then
			elementTable[elementName] = nil
		end
	end
	return elementTable
end

---This is for scrolling through EDF elements
function nextEDF ()
	for key, icons in pairs(edfResourcesNext[currentSelectedResource]) do
		guiSetVisible ( icons, false )
	end
	newKey = next ( edfResourcesNext, currentSelectedResource )
	if newKey == nil then 
		for key,value in pairs(edfResourcesNext) do
			newKey = key
			break
		end
	end
	for key, icons in pairs(edfResourcesNext[newKey]) do
		guiSetVisible ( icons, true )
	end
	currentSelectedResource = newKey
	if ( currentSelectedResource == defaultElementDefinition ) then 
		setSelectedResourceText ( "DEFAULT" )
	else
		setSelectedResourceText ( string.upper(currentSelectedResource) )
	end
end

function prevEDF ()
	for key, icons in pairs(edfResourcesNext[currentSelectedResource]) do
		guiSetVisible ( icons, false )
	end
	--we have to loop through to find the previous one
	local progress = 0
	local newKey
	for key, value in pairs(edfResourcesNext) do
		if ( key == currentSelectedResource ) then
			break
		end
		progress = progress + 1
	end
	if ( progress == 0 ) then
		for key,value in pairs(edfResourcesNext) do
			newKey = key
		end
	else
		local progressCheck = 1
		for key,value in pairs(edfResourcesNext) do
			if progressCheck == progress then
				newKey = key
				break
			end
			progressCheck = progressCheck + 1
		end
	end
	for key, icons in pairs(edfResourcesNext[newKey]) do
		guiSetVisible ( icons, true )
	end
	currentSelectedResource = newKey
	if ( currentSelectedResource == defaultElementDefinition ) then 
		setSelectedResourceText ( "DEFAULT" )
	else
		setSelectedResourceText ( string.upper(currentSelectedResource) )
	end
end

--This allows quick resizing of gui labels
function resetLabelCanvasSize ( label )
	local extent = guiLabelGetTextExtent ( label )
	local height = guiLabelGetFontHeight ( label )
	guiSetSize ( label, extent,16,false )
	return true
end

function guiCreateMinimalLabel(x,y,width,height,text,relative,parent)
	--Syntax 1 (allows for width and height)
	if ( relative ) then
		local label = guiCreateLabel(x,y,width,height,text,relative,parent)
		resetLabelCanvasSize ( label )
		return label
	else
	--Syntax 2 (x,y,text,relative,parent)
		local label = guiCreateLabel(x,y,screenX,screenY,width,height,text)
		resetLabelCanvasSize ( label )
		return label	
	end
end

--Stops gui input being enabled when the resource stops
addEventHandler ( "onClientResourceStop", thisResourceRoot,
	function()
		guiSetInputEnabled(false)
	end
)
