local wv = require 'nylon.debug'{ name = 'pls-theme' }

pcall( function() require 'NylonOs' end ) -- just to test for windows / not windows
local WINDOWS = (NylonOs and NylonOs.IsWindows())

local maxpairs = Pdcurses.Static.color_pairs()

wv.log('debug','WINDOWS=%s color_pairs returned=%d', WINDOWS, maxpairs)

--if maxpairs < 1 then -- linux curses returns 0, no idea why but it seems 
--   maxpairs = 8      -- to work if I say 8 anyway.  Maybe because I was
--end                  -- loading this file before calling curses init?

local assigned_pairs = {}
local free_pairs = {}
for i = 1,(maxpairs-1) do
   table.insert(free_pairs,i)
end


wv.log 'welcome to pls-theme'

local function get_color( fg, bg )
   local key = fg * 0x100000 + bg
   if assigned_pairs[key] then
      return assigned_pairs[key][1]
   else
      local pair = free_pairs[#free_pairs]
      table.remove(free_pairs,#free_pairs)
      wv.log('debug', 'add color theme, pair=%d fg=%d bg=%d',
             pair, fg, bg )
      local color = Pdcurses.Color(pair, fg, bg)
      assigned_pairs[key] = { color, pair }
      return color
   end
end



-- weird Windows/Pdcurses color things:
-- 
-- Pdcurses.Color.yellow is actually bright white, whereas 'white' is more like grey.
-- To get actual yellow, use color 'yellow' + 8
-- These Pdcurses colors are really messed up on windows.  Here's what they really
-- seem to be:
--
-- white => white
-- black => black
-- red => red
-- green => green
-- blue => blue
-- cyan => sort of teal?
-- magenta -> indigo?
-- yellow => bright white (??)
--
-- With bold attr,
-- white => bright white
-- black => gray
-- red => bright red
-- blue => bright blue
-- green => bright green
-- cyan => actually looks like cyan
-- magenta => actually looks like magenta
-- yellow => actually looks like yellow
-- 
-- red, blue, green seem correct but are dull.

local theme = {
   --               Foreground                 Background            bold
   normal  =     { Pdcurses.Color.white,    Pdcurses.Color.black,    false },
   inverse =     { Pdcurses.Color.black,    Pdcurses.Color.white,    false },
   inversehot =  { Pdcurses.Color.red,      Pdcurses.Color.white,    true },
   heading  =    { Pdcurses.Color.white,    Pdcurses.Color.black,    true },
   classicmenu = { Pdcurses.Color.yellow,   Pdcurses.Color.cyan ,    true },
   autotext =    { Pdcurses.Color.cyan,     Pdcurses.Color.black,    false },
   focuswinborder = { Pdcurses.Color.white,  Pdcurses.Color.black,   true },
}

if not WINDOWS then
--   theme.classicmenu = { Pdcurses.Color.black, Pdcurses.Color.cyan }
   theme.autotext = { Pdcurses.Color.cyan, Pdcurses.Color.black }
end	

local with = setmetatable( {}, {
      __index = function(t,v)
         local fgbg = theme[v]
         if fgbg then
            local color = get_color( fgbg[1], fgbg[2] )
            return function(win,withfun)
               if win then
                  win:attron( color )
                  if fgbg[3] then
                     win:attron( Pdcurses.Color.a_bold )
                  end
               end

               withfun()

               if win then
                  if fgbg[3] then
                     win:attroff( Pdcurses.Color.a_bold )
                  end
                  win:attroff( color )
               end
            end -- end, 'with' function
         end
      end })

return setmetatable( {
                        color = get_color,
                        with = with,
                     }, {
   __index = function(t,v)
      --wv.log('debug', 'request theme color=%s', v)
      local fgbg = theme[v]
      --wv.log('debug', 'request theme color=%s fgbg=%s', v, fgbg)
      if fgbg then
         return get_color( fgbg[1], fgbg[2] )
      end
   end } )