#!/usr/bin/env texlua

-- $Id: antpattern.lua 3 2020-11-22 22:25:36Z reinhard $

-- Copyright (C) 2020 Reinhard Kotucha <reinhard.kotucha@web.de>
-- 
-- You may freely use, modify, and/or distribute this file.

require('luagraphlib')
luagraphlib.import()

local fmt = string.format
local pi  = math.pi
local sin = math.sin
local cos = math.cos
local arc_tan = math.atan
local sqrt = math.sqrt

local color = dofile(kpse.find_file('namedcolors.lua'))

-- colors must be global if passed as arguments from TeX

-- gray color model
gray  = color.gray

-- rgb color model
rgb   = color.rgb
x11   = color.rgb.x11
svg   = color.rgb.svg

-- cmyk color model
cmyk  = color.cmyk
dvips = color.cmyk.dvips
hks   = color.cmyk.hks


function antpattern (filename, ...)
  local params = {}
  local fun
  
  for _,p in ipairs{...} do
    if type(p) == 'table' then
      params = p
    end
    if type(p) == 'function' then
      fun = p
    end
  end

  local default = default.antpattern

  if type(fun) ~= 'function' then
    fun = default.lambda or function (a) return a[1], a[2] end
  end

  local ref = params.offset or default.offset or 0
  local gainref = params.gainref or default.gainref or 'iso'
  local bgcolor = params.bgcolor or default.bgcolor or {1} --white
  local patternfillcolor = params.fillcolor or
    default.fillcolor or {0.85} 
  local patternstrokecolor = params.strokecolor or
    default.strokecolor or {0}

--  translate(60,60)
--  scale(1.2, 1.2)
  setlinewidth(pt(0.4))
  setlinejoin('round')
  setstrokecolor{0}
  
  local function dB_to_polar (t)
    local fixed = {}
    for _,coords in ipairs(t) do
      fixed[#fixed+1] = {40 - ref + coords[1], coords[2]}
      if fixed[#fixed][1] < 0 then fixed[#fixed][1] = 0 end
    end
    return fixed
  end
  
  local textscale = 0.8
  moveto(0,0)
  setfillcolor (bgcolor)
  circle(40)
  paint()

  to_path(polar_to_cartesian(
            dB_to_polar(
              readdatafile(filename, fun, ref))))

  closepath()
  
  setstrokecolor (patternstrokecolor)
  setfillcolor (patternfillcolor)
  paint()
  
  setstrokecolor{0}
  setlinewidth(pt(0.4))

  for i = 10, 30, 10 do
    moveto(0,0)
    circle(i)
    stroke()
  end

 
  for 𝜑 = 0, 350, 10 do
    gsave()
    rotate(𝜑)
    translate(45, 0)
    rotate(-90)
    text('\\phantom{$^\\circ$}'..𝜑..'$^\\circ$',
         {
           scale = textscale,
         }
    )
    grestore()
  end
  
  for 𝜑 = 15, 360, 15 do
    moveto(cartesian(5, 𝜑))
    lineto(cartesian(40, 𝜑))
    stroke()
  end
  
  for 𝜑 = 45, 360, 45 do
    moveto(cartesian(0, 𝜑))
    lineto(cartesian(40, 𝜑))
    stroke()
  end
  
  for 𝜑 = 1, 360 do
    moveto(cartesian(40, 𝜑))
    lineto(cartesian(42, 𝜑))
    stroke()
  end
  
  for 𝜑 = 5, 360, 5 do
    moveto(cartesian(40, 𝜑))
    lineto(cartesian(43, 𝜑))
    stroke()
  end
  
  for 𝜑 = 10, 360, 10 do
    moveto(cartesian(40, 𝜑))
    lineto(cartesian(44, 𝜑))
    stroke()
  end

  setstrokecolor(gray.black)
  setlinewidth(pt(0.4))
  for i = 10, 30, 10 do
    moveto(0,0)
    circle(i)
    stroke()
  end

  for 𝜑 = 0, 350, 10 do
    gsave()
    rotate(𝜑)
    translate(45, 0)
    rotate(-90)
    text('\\phantom{$^\\circ$}'..𝜑..'$^\\circ$',
         {
           scale = textscale,
         }
    )
    grestore()
  end
  
  for 𝜑 = 15, 360, 15 do
    moveto(cartesian(5, 𝜑))
    lineto(cartesian(40, 𝜑))
    stroke()
  end
  
  for 𝜑 = 45, 360, 45 do
    moveto(cartesian(0, 𝜑))
    lineto(cartesian(40, 𝜑))
    stroke()
  end
  
  for 𝜑 = 1, 360 do
    moveto(cartesian(40, 𝜑))
    lineto(cartesian(42, 𝜑))
    stroke()
  end
  
  for 𝜑 = 5, 360, 5 do
    moveto(cartesian(40, 𝜑))
    lineto(cartesian(43, 𝜑))
    stroke()
  end
  
  for 𝜑 = 10, 360, 10 do
    moveto(cartesian(40, 𝜑))
    lineto(cartesian(44, 𝜑))
    stroke()
  end

  for _,dB in ipairs{10, 20, 30} do
    local dBval = 40 - ref - dB
    local label = dBval..'$\\,$'
    if dBval > 0 then label = '$-$'..dBval..'$\\,$' end

    if ref > 0 then
      if gainref == 'iso' then
        label = label .. 'dB$_{\\rm i}$'
      elseif gainref == 'dipole' then
        label = label .. 'dB$_{\\rm d}$'
      end
    else
      label = label .. 'dB'
    end

    gsave()
      translate(dB, 0)
      translate(1, 0)
      rotate(270)
      text(label,
           {
             scale = textscale,
             sep = 1,
             framed = true,
             fillcolor = patternfillcolor,
             strokecolor = patternfillcolor,
           }
      )
    grestore()
  end
end

-- Local Variables:
--  mode: Lua
--  TeX-engine: luatex
--  lua-indent-level: 2
--  indent-tabs-mode: nil
--  coding: utf-8-unix
-- End:
-- vim:set tabstop=2 expandtab: