local lg = assert( love.graphics )
local math = math
local mat = require( "mat4" )

local DETAIL = 15
local CURVE = 45

local vertices = {}

local function radius( y )
  return math.max( 0,
    0.6 * math.pow( (1-y), 1/3 ) +
    0.1 * math.exp( -5*y ))
end

local loops = {}
for i = 1, CURVE do loops[i] = {} end

do
  local c, s = math.cos( 2*math.pi / DETAIL ), -math.sin( 2*math.pi / DETAIL )
  local n = 1
  local y = 0
  for i, loop in ipairs( loops ) do
    local x, z = 1, 0
    y = y + 1 / #loops
    local r = radius( y )
    for j = 1, DETAIL + 1 do
      --need the extra vertex so the texture wraps correctly
      local u = 5 * ( j - 1 ) / DETAIL
      local v =  3 * (1.0 - y) - 0.85
      vertices[ n ] = { r * x, y, r * z, u, v }
      loop[j] = n
      n = n + 1
      x, z = c*x+s*z, c*z-s*x
    end
  end
end

local function constructVertexMap()
  local map = {}
  local k = 1
  for i, loop in ipairs( loops ) do
    local nextLoop = loops[i+1]
    if not nextLoop then return map end
    for j, n in ipairs( loop ) do
      map[k] = n
      map[k+1] = nextLoop[j]
      k=k+2
    end
  end
end


local bellMesh = lg.newMesh(
  {--attributes
    {"VertexPosition", "float", 3},
    {"VertexTexCoord", "float", 2},
  },
  vertices,
  "strip",
  "static"
)

do
  local c, s = math.cos( 2*math.pi / 7 ), -math.sin( 2*math.pi / 7 )
  local instanceMesh = {}
  local x, z = 1, 0
  local r = 15
  for i = 1, 7 do
    instanceMesh[i] = { i / 2, r * x, r * z, (i-1)/6 }
    x, z = c*x+s*z, c*z-s*x
  end
  bellMesh:attachAttribute( "bellInstance",
    lg.newMesh({{"bellInstance","float",4}}, instanceMesh, nil, "static" ),
    "perinstance" )
end

bellMesh:setVertexMap( constructVertexMap() )
return bellMesh