
ext_regexp <- regexp(@".+\.[^./]+$")


function NONE() { return 0; }


function S(fn, loop=false, max=1, mindist=2, maxdist=256, volume=1)
{
  if (!ext_regexp.match(fn)) fn+=".wav"
  fn="sound/"+fn

  local s=load_sample(fn, max, SNDF_3D|(loop?SNDF_LOOP:0))
  set_sample_volume(s, volume)
  set_sample_dist(s, mindist, maxdist)
  return @() get_channel(s)
}


function S2D(fn, max=1, volume=1, loop=false)
{
  if (!ext_regexp.match(fn)) fn+=".wav"
  fn="sound/"+fn

  local s=load_sample(fn, max, (loop?SNDF_LOOP:0))
  set_sample_volume(s, volume)
  return @() get_channel(s)
}


function R(list, params={})
{
  if (typeof(list)=="string") list=split(list, " \r\n\t,;")

  local loop    = 0; if ("loop"    in params) loop   =params.loop
  local max    =  1; if ("max"     in params) max    =params.max
  local mindist=  2; if ("mind"    in params) mindist=params.mind
  local maxdist=128; if ("maxd"    in params) maxdist=params.maxd
  local volume =  1; if ("volume"  in params) volume =params.volume

  local newList=[]

  foreach (item in list)
  {
    if (typeof(item)=="string")
    {
      item=strip(item)
      if (item=="") continue;
      item=S(item, loop, max, mindist, maxdist, volume)
    }

    newList.append(item)
  }

  if (newList.len()==0) return @() 0;

  return @() newList[game_rnd()%newList.len()]()
}


function R2D(list, params={})
{
  if (typeof(list)=="string") list=split(list, " \r\n\t,;")

  local loop    = 0; if ("loop"    in params) loop   =params.loop
  local max    =  1; if ("max"     in params) max    =params.max
  local volume =  1; if ("volume"  in params) volume =params.volume

  local newList=[]

  foreach (item in list)
  {
    if (typeof(item)=="string")
    {
      item=strip(item)
      if (item=="") continue;
      item=S2D(item, max, volume, loop)
    }

    newList.append(item)
  }

  if (newList.len()==0) return @() 0;

  return @() newList[game_rnd()%newList.len()]()
}


//ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ//


cur_music <- 0


function do_music_chaining(prev)
{
  START_MUSIC(get_next_chained_music(prev), 0)()
}


function START_MUSIC(name, fade_time=200)
{
  if (!name) return NONE

  return function()
  {
    if (!(name in music)) return 0;
    local m=music[name]
    if (!m) return 0;

    if (cur_music!=m) fade_out_and_stop(cur_music, fade_time)

    local v=1
    if (name in music_volume) v=music_volume[name]

    cur_music=m
    set_channel_volume(m, v*global_music_volume)
    play_channel(m, true)
    return 0;
  }
}


function STOP_MUSIC(time=200)
{
  return function()
  {
    if (cur_music)
    {
      fade_out_and_stop(cur_music, time)
      cur_music=0;
    }
    return 0;
  }
}


function SEQ(...)
{
  local seq=vargv
  return function()
  {
    local c=0
    foreach (f in seq) c=f()
    return c;
  }
}
