-- Licence: MIT Licence
-- Some code from the luatz project (MIT Licence)

-- Configuration ==========
local dateformat = "%Y-%m-%d, %H:%M"
local dateformat_log = "%Y-%m-%d, %H:%M:%S"
local Colour_Not_Complete = "#FFB67D"
local Colour_Complete = "#000000"
local Colour_Heading_Complete = "#58FA58"


-- ========================
version= "12"
require( "iuplua" )
require( "iupluacontrols" )
dofile "../../SavedVariables/History.lua"
dofile "./data/data.lua"	--Achievement to Grid lookup, language independent

--os.execute( "md ..\\..\\SavedVariables\\History_Bak" )  -- fails silently if already exists.

--os.execute("copy  ..\\..\\SavedVariables\\History.lua ..\\..\\SavedVariables\\History_Bak\\History.lua")

--[[
-- ============== Setup storage for old characters.
archivef = io.open("../../SavedVariables/History.Archive", "r")
if archivef ==nil then	--create empty file
	archivef = io.open("../../SavedVariables/History.Archive", "w")
	archivef:write("Archive = {} \n")
end

archivef:close()
dofile "../../SavedVariables/History.Archive"

-- newf = assert(io.open("../../SavedVariables/History.new", "w"))
-- ==============
--]]
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end


-- Minimally effective quoting
function quote(astring)
	return '"' .. string.gsub(astring,"%'", "\\'") .. '"'
end


function write_saved(o)
--	local escaped
   if type(o) == 'table' then
      local s = '{\n'
      for k,v in pairs(o) do
         if type(k) ~= 'number' then
		 k = '"'..k..'"'
		 end
         s = s .. '['..k..'] = ' .. write_saved(v) .. ',\n'
      end
      return s .. '}\n'
   elseif
		type(o) == 'string' then
		return quote(o)
   else
		return tostring(o)
   end
end

lingua= {}		-- Translated data
function load_lang(lang)
	if lingua[lang] ~= nil
	then return
	end

	local path = "./data/" .. lang .. ".lua"
	dofile (path)
	lingua[lang] = {}

	lingua[lang].Area_names = Area_names		-- dofile writes to global variables
	lingua[lang].L = L
	lingua[lang].pub_names = pub_names
	lingua[lang].grp_names = grp_names
	lingua[lang].Ach_Detail = Ach_Detail
end

--SQ_Dat loaded  from data.lua
SQ_Info= {} -- keyed by "LC" string as the  ZONE Identifier
for id,_ in pairs (SQ_dat) do  -- Load all Quest Data by Achievement ID
		local L = SQ_dat[id].L
		local C = SQ_dat[id].C
		local key = tostring(L) .. tostring(C)	-- make name key

		if SQ_Info[key] == nil then
			SQ_Info[key] = {}
			SQ_Info[key].quests = {}
		end
		table.insert(SQ_Info[key].quests,id)
end


accounts = {}
accounts_list = {}		-- String list for selection dialog
naccounts = 0
for i,_ in pairs(History_SV["Default"]) do
	accounts[i] = {}
	accounts[i].names = {}	-- intermediate table for sorting. WIP. Array formatted.
	accounts[i].name = {}
	naccounts = naccounts +1
	table.insert(accounts_list, i)
end

function write_data()
  newf = assert(io.open("../../SavedVariables/History.new", "w"))
  newf:write("History_SV=" .. write_saved(History_SV))
  newf:close()
end
--Dump it back out
-- newf:write("History_SV=" .. write_saved(History_SV))
-- newf:close()



-- Load up .names, as a first run through. It's a sortable array.
-- This is used as an indirection to control presentation order
 for acc,_ in pairs (accounts) do
  for char, _ in pairs(History_SV["Default"][acc]["$AccountWide"]["data"]) do
      table.insert (accounts[acc].names, char)
	  accounts[acc].name[char] = {}		-- stub table to hold char data
  end
 end


function print_old()
	for i,j in pairs (History_SV["Default"][myaccount]["$AccountWide"]["old"]) do
		print (i .. " .. " .. dump(j))
	end
end

-- set up some static data


--[[ ==========================================
	Iterate over all accounts and chars creating display items
--]]
 for acc,_ in pairs (accounts) do
  -- ===	Load Language Tables
    accounts[acc].lang = (History_SV["Default"][acc]["$AccountWide"].lang)
	if accounts[acc].lang == nil then
	accounts[acc].lang = "en"
	end
	load_lang(accounts[acc].lang)
	-- Reset Globals
	Area_names = lingua[accounts[acc].lang].Area_names
	L = lingua[accounts[acc].lang].L
	pub_names = lingua[accounts[acc].lang].pub_names
	grp_names = lingua[accounts[acc].lang].grp_names
	Ach_Detail = lingua[accounts[acc].lang].Ach_Detail

  -- ====  Accountwide Data
  -- Setup Log data
	accounts[acc].logtabs  =iup.tabs{}
	-- Log Display table presentation
	accounts[acc].logtable = {}
	accounts[acc].logtable=iup.matrix{numcol=2, numcol_visible=2,  numlin=0,numlin_visible=8}
	accounts[acc].logtable:setcell(0,0, L.TStamp)
	iup.SetAttribute(accounts[acc].logtable,  "ALIGNMENT0", "ACENTER")
	iup.SetAttribute(accounts[acc].logtable,  "ALIGNMENT2", "ALEFT")
	iup.SetAttribute(accounts[acc].logtable,  "WIDTH0", 80)
	iup.SetAttribute(accounts[acc].logtable,  "WIDTH1", 100)
	iup.SetAttribute(accounts[acc].logtable,  "WIDTH2", 300)
	iup.SetAttribute(accounts[acc].logtable,  "READONLY", "YES")
	-- Load log data

	local Line=0
	local TimeStr = ""
	accounts[acc].logtable.numlin = Line
	for _,j in ipairs (History_SV["Default"][acc]["$AccountWide"]["log"]) do
		Line= Line +1
		accounts[acc].logtable.numlin = Line
		TimeStr = os.date(dateformat_log,j["TimeStamp"])
		accounts[acc].logtable:setcell( Line,0, TimeStr)
		if j["Char"] ~= nil then
			accounts[acc].logtable:setcell( Line,1, j["Char"])
		end
		accounts[acc].logtable:setcell( Line,2, j["text"])
	end

	-- Setup Log Display
	accounts[acc].log_tab=iup.vbox {
			["tabtitle"] =L.LogTab,
			accounts[acc].logtable,
			iup.fill{}
			}
	-- Top Level Panels
	accounts[acc].mode_zbox = iup.zbox{}  -- display main panel containing tabs and dungeons
	accounts[acc].char_tabs = iup.tabs{}  -- Top level of Char_Tabs, Character Info in Here
	accounts[acc].dung_tabs = iup.tabs{}  -- Top level of Dung_Tabs, Dungeon  Info in Here

	accounts[acc].Status_bar = iup.label{title=L.Welcome, expand = "HORIZONTAL"}

	iup.Append(accounts[acc].mode_zbox, accounts[acc].char_tabs)
	iup.Append(accounts[acc].mode_zbox, accounts[acc].dung_tabs)

	--demo data
	iup.Append(accounts[acc].dung_tabs,
			iup.vbox {
				["tabtitle"] = "DUNG",
				iup.label{title="label"},
				iup.fill{},
			}
			)


  -- Mode Buttons (Toggles)
  --[[  These control the display.
   Char mode lists the characters and information for them (default for prior versions)
   Dung Mode lists the dungeons and which characters have done them.
   Buttons are arranged in radio mode
   --]]

   accounts[acc].char_tog = iup.toggle{ title = "Characters"}
  local tog = accounts[acc].char_tog
  function tog:action(x)
	if x == 1 then
	accounts[acc].mode_zbox.value =accounts[acc].char_tabs
	end
  end

  accounts[acc].dung_tog = iup.toggle{ title = "Dungeons"}

  local tog = accounts[acc].dung_tog
  function tog:action(x)
	if x == 1 then
	accounts[acc].mode_zbox.value = accounts[acc].dung_tabs
	end
  end
  accounts[acc].mode = iup.frame {
								iup.radio {
								iup.hbox{
										accounts[acc].char_tog,
										accounts[acc].dung_tog,
										},
									}
								}
  accounts[acc].mode.title =  "Mode"
  accounts[acc].mode.margin = "15x5"
  -- ====  END Accountwide Data

-- Creates boxes, stage from names to allow optional sorting in future.
	for _,char in ipairs(accounts[acc].names) do
		local me = accounts[acc].name[char]											-- shorter reference: our code
		local thischar = History_SV["Default"][acc]["$AccountWide"]["data"][char]	-- shorter reference: History DB
		-- Pull in some char data for processing
		-- == Gender
		if thischar.Gender =="M" then
			me.gender = L.Male
		elseif thischar.Gender == "F" then
			me.gender = L.Female
		end
		-- ==Level
		local level = thischar.level

		me.level = level
		if (level <=50) then
			me.levelstr = tostring(level)
		else
			me.levelstr = "V" .. tostring(level -50)
		end
		-- == Cumulative TimePlayed
		me.timeplayed = math.floor(thischar.levels[level].time/60)

		-- Generate the leveling box.  ============================
--		local leveling_box = {}
		me.leveling_box = iup.matrix {numcol=6, numcol_visible=6,  widthdef=60}
		me.leveling_box:setcell(0,1, L.Level)
		me.leveling_box:setcell(0,2, L.PTime)
		me.leveling_box:setcell(0,3, L.Start)
		me.leveling_box:setcell(0,4, L.Deaths)
		me.leveling_box:setcell(0,5, L.APts)
		me.leveling_box:setcell(0,6, L.Location)
		iup.SetAttribute(me.leveling_box, "WIDTH6", "100")
		iup.SetAttribute(me.leveling_box, "READONLY", "YES")


		-- levels as stored are unsorted, so create a level table which is sorted,
		local levels = {}
		for i,_ in pairs(thischar.levels) do
			table.insert(levels, i)
		end

		table.sort(levels)

		for i,j in ipairs(levels) do		-- traverse in sorted order
			local timelevel = math.floor(thischar.levels[j].time)
			me.leveling_box.numlin = i
			me.leveling_box:setcell(i,1, j)
			me.leveling_box:setcell(i,2, math.floor(timelevel/60))
			me.leveling_box:setcell(i,3, os.date("%Y-%m-%d",thischar.levels[j].begin))
			me.leveling_box:setcell(i,4, thischar.levels[j].deaths)
			me.leveling_box:setcell(i,5, thischar.levels[j].Ach_Points)
			-- Do we have map name for this level?
			if thischar.levels[j].map ~= nil then
				me.leveling_box:setcell(i,6, thischar.levels[j].map)
			end
		end
		-- Create Grp Dungeon Achievements Box=========================
		me.Grp_box = {}
		me.Grp_box = iup.matrix {numcol=4, numcol_visible=4,  numlin=5, widthdef=90}
		--Set Column titles
		for i=1, 4 do
			me.Grp_box:setcell(0,i, Area_names[i].long)
		end
		--set lines
		me.Grp_box:setcell(0,0, L.Level)
		me.Grp_box:setcell(1,0, "10+")
		me.Grp_box:setcell(2,0, "17+")
		me.Grp_box:setcell(3,0, "24+")
		me.Grp_box:setcell(4,0, "31+")
		me.Grp_box:setcell(5,0, "38+")

		iup.SetAttribute(me.Grp_box, "READONLY", "YES")

		-- set all text to red
		iup.SetAttribute(me.Grp_box,  "FGCOLOR*:1", Colour_Not_Complete)
		iup.SetAttribute(me.Grp_box,  "FGCOLOR*:2", Colour_Not_Complete)
		iup.SetAttribute(me.Grp_box,  "FGCOLOR*:3", Colour_Not_Complete)
		iup.SetAttribute(me.Grp_box,  "FGCOLOR*:4", Colour_Not_Complete)


		-- set text to black if achievement found.
		for id,_ in pairs (grp_dat) do
			local colour
			if thischar.ach[id] ~= nil then
				colour = "FGCOLOR" .. grp_dat[id].L .. ":" .. grp_dat[id].C
				iup.SetAttribute(me.Grp_box, colour, Colour_Complete)
			end
		end

		--Set background of heading if all done
		if thischar.ach[1073] ~= nil then  --EP Vanquisher
				iup.SetAttribute(me.Grp_box,  "BGCOLOR0:1", Colour_Heading_Complete)
		end

		if thischar.ach[1074] ~= nil then  --DC Vanquisher
				iup.SetAttribute(me.Grp_box,  "BGCOLOR0:2", Colour_Heading_Complete)
		end

		if thischar.ach[1075] ~= nil then  --AD Vanquisher
				iup.SetAttribute(me.Grp_box,  "BGCOLOR0:3", Colour_Heading_Complete)
		end

		local key = ""
		local dname = ""
		for id,_ in pairs (grp_dat) do
				local L = grp_dat[id].L
				local C = grp_dat[id].C
				key = tostring(L).. tostring(C)	-- make name key
				dname = grp_names[key]
					if dname == nil then
				dname = "key " .. key .." not found"
				end
			--	print(key .. "   " .. dname)
				me.Grp_box:setcell(L, C, dname)
		end

		me.Grp_box.Redraw= "ALL"

		-- Create Pub Dungeon Achievements Box==========================
		me.Pub_box = iup.matrix {numcol=4, numcol_visible=4,  numlin=5, widthdef=90}
		for i=1, 4 do  -- Load text
			me.Pub_box:setcell(0,i, Area_names[i].long)
		end

		me.Pub_box:setcell(0,0, L.Level)
		me.Pub_box:setcell(1,0, "12-15")
		me.Pub_box:setcell(2,0, "20-23")
		me.Pub_box:setcell(3,0, "35-36")
		me.Pub_box:setcell(4,0, "40-43")
		me.Pub_box:setcell(5,0, "47-50")

		iup.SetAttribute(me.Pub_box, "READONLY", "YES")

		iup.SetAttribute(me.Pub_box,  "FGCOLOR*:1", Colour_Not_Complete)
		iup.SetAttribute(me.Pub_box,  "FGCOLOR*:2", Colour_Not_Complete)
		iup.SetAttribute(me.Pub_box,  "FGCOLOR*:3", Colour_Not_Complete)
		iup.SetAttribute(me.Pub_box,  "FGCOLOR*:4", Colour_Not_Complete)

		for id,_ in pairs (pub_dat) do
			if thischar.ach[id] ~= nil then
				local colour = "FGCOLOR" .. pub_dat[id].L .. ":" .. pub_dat[id].C
				iup.SetAttribute(me.Pub_box, colour, Colour_Complete)
			end
		end

		if thischar.ach[1068] ~= nil then  --EP Conqueror
				iup.SetAttribute(me.Pub_box,  "BGCOLOR0:1", Colour_Heading_Complete)
		end

		if thischar.ach[1070] ~= nil then  --DC Conqueror
				iup.SetAttribute(me.Pub_box,  "BGCOLOR0:2", Colour_Heading_Complete)
		end

		if thischar.ach[1069] ~= nil then  --AD Conqueror
				iup.SetAttribute(me.Pub_box,  "BGCOLOR0:3", Colour_Heading_Complete)
		end

		for id,_ in pairs (pub_dat) do  -- Load text
				local L = pub_dat[id].L
				local C = pub_dat[id].C
				key = tostring(tostring(L) .. tostring(C))	-- make name key
				dname = pub_names[key]
					if dname == nil then
				dname = "key " .. key .." not found"
				end
				me.Pub_box:setcell(L,C,dname)
		end

		me.Pub_box.Redraw= "ALL"

		-- Create Vet Dungeon Achievements Box==========================
		me.Vet_box= iup.matrix {numcol=5, numcol_visible=5,  numlin=5, widthdef=110}

		for i=1, 5 do  -- Load headings
			me.Vet_box:setcell(0,i, Area_names[i].long)
		end

		iup.SetAttribute(me.Vet_box, "READONLY", "YES")
		iup.SetAttribute(me.Vet_box, "WIDTH4", "0")		-- Hide Coldharbour, Empty

		iup.SetAttribute(me.Vet_box,  "FGCOLOR*:1", Colour_Not_Complete)
		iup.SetAttribute(me.Vet_box,  "FGCOLOR*:2", Colour_Not_Complete)
		iup.SetAttribute(me.Vet_box,  "FGCOLOR*:3", Colour_Not_Complete)
		iup.SetAttribute(me.Vet_box,  "FGCOLOR*:4", Colour_Not_Complete)
		iup.SetAttribute(me.Vet_box,  "FGCOLOR*:5", Colour_Not_Complete)

		-- Need to keep track of multiple achievements in Vet dungeons. Index them by dungeon LineColumn.
		Vet_Info={}
		for id,_ in pairs (vet_dat) do  -- Load Dungeons Name. Info LC is the Dungeon Identifier
				local L = vet_dat[id].L
				local C = vet_dat[id].C
				key = tostring(L) .. tostring(C)	-- make name key
				dname = grp_names[key]				-- Vet Dungeons are grp
					if dname == nil then
				dname = "key " .. key .." not found"
				end
				Vet_Info[key] = {count = 0}
				me.Vet_box:setcell(L,C,dname .. " (0)")
		end


		for id,_ in pairs (vet_dat) do  -- For Achievements we have..
			if thischar.ach[id] ~= nil then
				local L = vet_dat[id].L
				local C = vet_dat[id].C
				--Set colour of LC
				local colour = "FGCOLOR" .. L .. ":" .. C
				iup.SetAttribute(me.Vet_box, colour, Colour_Complete)

				key = tostring(L) .. tostring(C)	-- make name key
				dname = grp_names[key]				-- Vet Dungeons are grp
					if dname == nil then
				dname = "key " .. key .." not found"
				end
				-- Increment count and display
				Vet_Info[key].count = Vet_Info[key].count+1
				me.Vet_box:setcell(L,C,dname .. " (" .. Vet_Info[key].count ..")")
			end
		end

		if thischar.ach[1159] ~= nil 	then -- Coh All special.
			iup.SetAttribute(me.Vet_box, "FGCOLOR3:3", Colour_Heading_Complete)
		end

		if thischar.ach[1139] ~= nil 	then -- Craglorn all special.
			iup.SetAttribute(me.Vet_box, "BGCOLOR0:5", Colour_Heading_Complete)
		end

		me.Vet_box.Redraw= "ALL"

		-- Create Locations Box==============================================
		me.Map_box= iup.matrix {numcol=6, numcol_visible=6,  numlin=0, widthdef=70}

		me.Map_box:setcell(0,0, L.Location)
		me.Map_box:setcell(0,1, L.Visits)
		me.Map_box:setcell(0,2, L.FirstVisited)
		me.Map_box:setcell(0,3, L.FirstLevel)
		me.Map_box:setcell(0,4, L.TimesLeveled)
		me.Map_box:setcell(0,5, L.FirstDeath)
		me.Map_box:setcell(0,6, L.Deaths)

		iup.SetAttribute(me.Map_box, "READONLY", "YES")
		iup.SetAttribute(me.Map_box, "ALIGNMENT0", "ALEFT")
		iup.SetAttribute(me.Map_box, "WIDTH0", "100")
		iup.SetAttribute(me.Map_box, "WIDTH1", "40")
		iup.SetAttribute(me.Map_box, "WIDTH4", "55")
		iup.SetAttribute(me.Map_box, "WIDTH6", "40")


		local map_names = {}
		for map,_ in pairs(thischar.maps) do
			table.insert(map_names,map)
		end

		table.sort(map_names)
		local Line =1
		for _, map in ipairs(map_names) do
			me.Map_box.numlin = Line

			me.Map_box:setcell( Line,0, map)

			if thischar.maps[map].visit ~= nil then
				me.Map_box:setcell( Line,1, thischar.maps[map].visit)
			end

			if thischar.maps[map].firstvisitdate ~= nil then
				local firstvisit = os.date(dateformat,thischar.maps[map].firstvisitdate)
				me.Map_box:setcell( Line,2, firstvisit)
			end

			if thischar.maps[map].firstlevel ~= nil then
				me.Map_box:setcell( Line,3, thischar.maps[map].firstlevel)
			end

			if thischar.maps[map].timeslevel ~= nil then
				me.Map_box:setcell( Line,4, thischar.maps[map].timeslevel)
			end

			if thischar.maps[map].firstdeathlevel ~= nil then
				me.Map_box:setcell( Line,5, thischar.maps[map].firstdeathlevel)
			end

			if thischar.maps[map].deaths ~= nil then
				me.Map_box:setcell( Line,6, thischar.maps[map].deaths )
			end
		Line= Line +1
		end
-- Create WorldBoss Achievements Box==========================
		me.WB_box= iup.matrix {numcol=4, numcol_visible=4,  numlin=5, widthdef=110}

		for i=1, 4 do  -- Load headings, not craglorn
			me.WB_box:setcell(0,i, Area_names[i].long)
		end
		me.WB_box:setcell(0,0, L.Zone)
		me.WB_box:setcell(1,0, "1")
		me.WB_box:setcell(2,0, "2")
		me.WB_box:setcell(3,0, "3")
		me.WB_box:setcell(4,0, "4")
		me.WB_box:setcell(5,0, "5")
		iup.SetAttribute(me.WB_box, "READONLY", "YES")
		iup.SetAttribute(me.WB_box, "ALIGNMENT0", "ACENTER")

		iup.SetAttribute(me.WB_box,  "FGCOLOR*:1", Colour_Not_Complete)
		iup.SetAttribute(me.WB_box,  "FGCOLOR*:2", Colour_Not_Complete)
		iup.SetAttribute(me.WB_box,  "FGCOLOR*:3", Colour_Not_Complete)
		iup.SetAttribute(me.WB_box,  "FGCOLOR*:4", Colour_Not_Complete)
		iup.SetAttribute(me.WB_box,  "FGCOLOR*:5", Colour_Not_Complete)

		-- Need to keep track of multiple achievements for WB in Zones. Index them by zone LineColumn.
		WB_Info={}
		WB_Area={}
		for id,_ in pairs (WB_dat) do  -- Load World Boss Name. Info LC is the ZONE Identifier
				local L = WB_dat[id].L
				local C = WB_dat[id].C
				key = tostring(L) .. tostring(C)	-- make name key
				dname = Locations[key]				-- Zone Locations
				if dname == nil then
					dname = "key " .. key .." not found"
				end
				WB_Info[key] = {count = 0}
				WB_Area[C] =0
				me.WB_box:setcell(L,C,dname .. " (0)")
		end

		for id,_ in pairs (WB_dat) do  -- For Achievements we have..
			if thischar.ach[id] ~= nil then
				local L = WB_dat[id].L
				local C = WB_dat[id].C
				--Set colour of LC
				local colour_cell = "FGCOLOR" .. L .. ":" .. C

				key = tostring(L) .. tostring(C)	-- make name key
				dname = Locations[key]				-- Zone Locations
				if dname == nil then
					dname = "WB key " .. key .." not found"
				end
				-- Increment count and display
				WB_Info[key].count = WB_Info[key].count+1
				me.WB_box:setcell(L,C,dname .. " (" .. WB_Info[key].count ..")")
				--Check if done
				if  WB_Info[key].count >= 6 then
					iup.SetAttribute(me.WB_box, colour_cell , Colour_Complete)
				end
				--Add to Area Completion
				WB_Area[C] = WB_Area[C] +1
			end
		end
		--Set Column Colours if 30 done.
		for i,j in pairs (WB_Area) do
			if j > 29 then
				iup.SetAttribute(me.WB_box,  "BGCOLOR0:".. tostring(i), Colour_Heading_Complete)
			end
		end

-- Create SkillQuest Achievements Box==========================

		me.SQ_box= iup.matrix {numcol=4, numcol_visible=4,  numlin=5, widthdef=110}
		me.SQ_Info = {}
		for i=1, 4 do  -- Load headings, not craglorn
			me.SQ_box:setcell(0,i, Area_names[i].long)
		end
		me.SQ_box:setcell(0,0, L.Zone)
		me.SQ_box:setcell(1,0, "1")
		me.SQ_box:setcell(2,0, "2")
		me.SQ_box:setcell(3,0, "3")
		me.SQ_box:setcell(4,0, "4")
		me.SQ_box:setcell(5,0, "5")
		iup.SetAttribute(me.SQ_box, "READONLY", "YES")
		iup.SetAttribute(me.SQ_box, "ALIGNMENT0", "ACENTER")

		iup.SetAttribute(me.SQ_box,  "FGCOLOR*:1", Colour_Not_Complete)
		iup.SetAttribute(me.SQ_box,  "FGCOLOR*:2", Colour_Not_Complete)
		iup.SetAttribute(me.SQ_box,  "FGCOLOR*:3", Colour_Not_Complete)
		iup.SetAttribute(me.SQ_box,  "FGCOLOR*:4", Colour_Not_Complete)
		iup.SetAttribute(me.SQ_box,  "FGCOLOR*:5", Colour_Not_Complete)

		-- Need to keep track of multiple achievements for SQ in Zones. Index them by zone LineColumn.

		local ccount, count
		-- Set up box with default data, and adjust
		for C=1, 4 do
			ccount = 0		-- per column
			for L = 1, 5 do
				key = tostring(L) .. tostring(C)	-- make name key
				dname = Locations[key]				-- Zone Locations
				if dname == nil then
					break	-- only 1 in Coldharbour
				end

				count = 0
				for _, id in ipairs (SQ_Info[key].quests) do	-- get the quests of the zone

					if  thischar.ach[id] ~= nil then	-- Have we got it?
						count =count +1
					end
				end
				ccount = ccount + count		-- Track the faction (Column)
				me.SQ_box:setcell(L,C,dname .. " (" .. tostring(count) .. ")")

				local colour = "FGCOLOR" .. L .. ":" .. C
				if count == #SQ_Info[key].quests then		-- Got them all??
					iup.SetAttribute(me.SQ_box, colour , Colour_Complete)  -- Yup
				end
			end   -- L

			--Set Column Heading Colours
			if ccount >= 15 then
				iup.SetAttribute(me.SQ_box, "BGCOLOR0:" .. tostring(C), Colour_Heading_Complete)
			end
		end		-- C
---
-- Create SkillQuest Achievements Detail Boxes=======================

		me.SQ_Detail_box = {}
		me.SQ_Detail_Zbox = iup.zbox{}

		local name, link
		for key, info in pairs(SQ_Info) do	-- for each zone
		--	print ("LAng: "..lang .. "  " ..key, dump(info))
			me.SQ_Detail_box[key]= iup.matrix {numcol=2, numcol_visible=2,  numlin=0}

			local Line = 1
			me.SQ_Detail_box[key]:setcell(0,0, L.Ach_ID)
			me.SQ_Detail_box[key]:setcell(0,1, L.Name)
			me.SQ_Detail_box[key]:setcell(0,2, L.Link)
			iup.SetAttribute(me.SQ_Detail_box[key], "READONLY", "YES")
			iup.SetAttribute(me.SQ_Detail_box[key], "ALIGNMENT0", "ACENTER")
			iup.SetAttribute(me.SQ_Detail_box[key], "ALIGNMENTLIN0", "ALEFT")
			iup.SetAttribute(me.SQ_Detail_box[key], "ALIGNMENT1", "ALEFT")
			iup.SetAttribute(me.SQ_Detail_box[key], "ALIGNMENT2", "ALEFT")
			iup.SetAttribute(me.SQ_Detail_box[key],"WIDTH0", "30")
			iup.SetAttribute(me.SQ_Detail_box[key],"WIDTH1", "150")
			iup.SetAttribute(me.SQ_Detail_box[key],"WIDTH2", "250")
			for _, id in ipairs (info.quests) do	-- get the quests of the zone
				me.SQ_Detail_box[key].numlin = Line
				me.SQ_Detail_box[key]:setcell(Line,0, tostring(id))

				if Ach_Detail[id] == nil then
					name = "UNKN"
				else
					name = Ach_Detail[id].name
				end
				link = SQ_dat[id].link1
				me.SQ_Detail_box[key]:setcell(Line,1, name)
				me.SQ_Detail_box[key]:setcell(Line,2, link)
				-- Set Detail Colours on achievement
				if thischar.ach[id] == nil  then
					iup.SetAttribute(me.SQ_Detail_box[key],"FGCOLOR" .. tostring(Line) .. ":*", Colour_Not_Complete)	-- Nope
				end

				Line= Line+1
			end
		-- Click on Link,
		local thisSQDetail = me.SQ_Detail_box[key]	-- The function def below doesn't like the [key]
		function thisSQDetail:click_cb(L,C)
				if C == 2 then
					iup.Help(self:getcell(L,C))		-- Launch Browser
				else
					return IUP_IGNORE
				end
			end

			iup.Append(me.SQ_Detail_Zbox, me.SQ_Detail_box[key])
		end

		function me.SQ_box:enteritem_cb(L,C)
			me.SQ_Detail_Zbox.value = me.SQ_Detail_box[tostring(L) .. tostring(C)]
		end


	 -- ====================================
	--  == Prepare for the character data display tabs
		me.tab = iup.vbox{
					["tabtitle"] = char,		-- This vbox will be a tab and the tab text is this

					iup.hbox{		--Top Information bar
							Alignment = "ACENTER",
							iup.label{title=me.gender, FONT="Times,BOLD,10"},
							iup.label{title=thischar.Race .." / ".. thischar.Class, PADDING="10X0", FONT="Times,BOLD,10"},
							iup.label{title=thischar.Alliance, PADDING="10X0"},
							iup.label{title=L.Level .. ": ".. me.levelstr, PADDING="10X0"},
							iup.label{title=L.Created .. os.date(dateformat,thischar.Created), PADDING="10X0"},
							iup.label{title=L.LLog .. os.date(dateformat,thischar.LoginTime), PADDING="10X0"},
							iup.label{title=L.TPlayed .. me.timeplayed .." " .. L.Hrs},
							iup.fill{}
							},
					iup.label{SEPARATOR="HORIZONTAL"},
					iup.vbox {		--Data tabs for Char
						iup.tabs { iup.vbox {	["tabtitle"] =L.GrpDungeon,
												iup.label{title=L.GrpLab,expand="HORIZONTAL"},
												me.Grp_box,
												iup.fill{}
											},
									iup.vbox {	["tabtitle"] =L.PubDungeon,
												iup.label{title=L.PubLab,expand="HORIZONTAL"},
												me.Pub_box,
												iup.fill{}
											},
									iup.vbox {	["tabtitle"] =L.VetDungeon,
												iup.label{title=L.VetLab,expand="HORIZONTAL"},
												me.Vet_box,
												iup.fill{}
											},

									iup.vbox {	["tabtitle"] =L.Leveling,
										--		iup.label{title="LevLabel",expand="HORIZONTAL"},
												me.leveling_box,
												iup.fill{}
											},
									iup.vbox {	["tabtitle"] =L.Locations,
											--	iup.label{title="LevLabel",expand="HORIZONTAL"},
												me.Map_box,
												iup.fill{}
											},
									iup.vbox {	["tabtitle"] =L.WBosses,
												iup.label{title=L.WBLab,expand="HORIZONTAL"},
												me.WB_box,
												iup.fill{}
											},
									iup.vbox {	["tabtitle"] =L.SkillQuests,
												iup.label{title=L.SkillLab,expand="HORIZONTAL"},
												me.SQ_box,
												iup.label{title=L.Detail},
												me.SQ_Detail_Zbox,
												iup.fill{}
											},

								},	-- end of tabs for dungeons
							},
					}  -- end of tabs for characters vbox

		iup.Append(accounts[acc].char_tabs,me.tab)

		local panel =(#accounts[acc].names * 90)
		if panel < 680  then
			panel = 680
		elseif panel >950 then
			panel = 950
		end
		accounts[acc].panelsize =  tostring(panel) ..  "x300"
	end  -- Chars

-- Add to end of Characters
iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
end -- Accounts

--print_old()



function select_account()
	local selected
		if naccounts > 1 then
			selected = iup.ListDialog (1, L.SelectA,
					2,	--Size
					accounts_list,
					1, --Initial
					1,naccounts	--MaxCol MaxLine
					)

			if selected <0 then
				return nil		-- Cancelled
			else
				return accounts_list[selected+1]
			end
		else
		return accounts_list[1]		-- only 1 account, no need for Dialog
		end
end


-- Create dialog to choose account
myaccount=select_account()


if myaccount ~=nil then
	-- Create dialog if not canceled
	dlg = iup.dialog{iup.vbox{
							accounts[myaccount].mode,
							accounts[myaccount].mode_zbox,
							iup.hbox{accounts[myaccount].Status_bar,	-- Bottom Status bar.
									iup.fill{},
									},
							margin="5x5",
							ngap="3",
							},
					title=L.title .. myaccount,
					size=accounts[myaccount].panelsize
					}
	-- Shows dialog in the center of the screen
	dlg:showxy(iup.CENTER, iup.CENTER)

	if (iup.MainLoopLevel()==0) then
	  iup.MainLoop()
	end
end