#!/bin/bash

# leveldir.sh
# Functions that update user's level directory

function make_levelgroup () { # args: levelgroup
  ## creates a directory for the levelgroup in level structure
  [ -z "$1" ] && return
  local path=""
  local levelgroup="`echo $1 | sed 's/\//~/g'`"
  local old_IFS="$IFS"
  IFS="~"
  for segment in $levelgroup; do
    path="$path/$segment"
    [ -d "$levels$path" ] || mkdir "$levels$path"
  done
  IFS="$old_IFS"
}

function make_group_levelinfo () { # args: levelinfo filename, levelgroup
  ## makes a levelinfo.conf for a levelgroup, autodetecting values
  ## note: i'm not capable of autodetecting the author value, but
  ## as far as I know, it isn't used anywhere in the game anyway
  local priority=200
  [ "${2:0:9}"  == "Tutorials" ] && priority=10
  [ "${2:0:13}" == "Classic Games" ] && priority=100
  [ "${2:0:25}" == "Additional Classic Levels" ] && priority=150
  [ "${2:0:8}"  == "Examples" ] && priority=800
  
  local name="`echo "${2##*/}" | tr _ ' '`"
  
  echo "file_identifier:                ROCKSNDIAMONDS_LEVELINFO_FILE_VERSION_3.0" > "$1"
  echo "name:                           $name" >> "$1"
  echo "author:                         Several authors" >> "$1"
  echo "sort_priority:                  $priority" >> "$1"
  echo "level_group:                    true" >> "$1"
}

# helper functions for update_levelgroups()
function update_levelgroups_test_levelgroup () { # args: levelgroup/levelset
  ## this checks if the the arg is levelgroup
  ## note that this doesn't detect empty levelgroup
  [ -z "`ls $path/*.level $path/*.tape 2>/dev/null`" ] || return
  [ -f $path/*[^lm]info.conf ] && return
  [ -z "`ls -d $path/*/ 2>/dev/null`" ] && return
  [ -z "`find -L $path -mindepth 2 -name "*.level"`" ] && return
  dirtype=levelgroup
}
function update_levelgroups_test_empty_levelgroup () { # args: levelgroup/levelset
  ## this checks if the arg is empty levelgroup
  [ -z "`find -L "$1" -mindepth 1 ! -type f`" ] || return
  [ -z "`find -L "$1" -type f ! -iname "levelinfo.*" ! -iname "*.txt"`" ] || return
  if [ -f "$path/levelinfo.conf" ]; then
    [ -z "`grep level_group "$path/levelinfo.conf" | grep "true"`" ] && return
  fi
  if [ -f "$path/levelinfo.conf.bak" ]; then
    [ -z "`grep level_group "$path/levelinfo.conf.bak" | grep "true"`" ] && return
  fi
  [ -f $path/*[^lm]info.conf ] && return # if it contains graphics/music/sounds/...-info.conf
  dirtype=emptygroup
}
function update_levelgroups () {
  ## removes levelinfo.conf from empty levelgroups, thus preventing
  ## them from showing in the levels list, and adds levelinfo.conf to
  ## levelgroups that are no longer empty
  levelgroups=''
  for path in `find "$levels" -mindepth 1 -type d`; do
    # get the type of the directory; only level groups interest us
    # first some basic test to filter most stuff
    [ -f $path/001.level ] && continue # it's a levelset
    [ "${path##*/}" == "tapes" -o "${path##*/}" == "scores" ] && continue
    # we have to make more advanced testing
    local dirtype=other # other means levelset, graphics, music, etc.
    update_levelgroups_test_levelgroup "$path"
    update_levelgroups_test_empty_levelgroup "$path"
    # only levelgroups interest us
    [ $dirtype == other ] && continue
    
    levelgroups="$levelgroups$newline${path#$levels/}"
    
    # is the levelgroup empty?
    if [ $dirtype == emptygroup ]; then
      # yes, it is; remove levelinfo.conf
      if [ -f "$path/levelinfo.conf" ]; then
        mv "$path/levelinfo.conf" "$path/levelinfo.conf.bak"
      fi
    else
      # it isn't empty; use its real levelinfo.conf
      if [ ! -f "$path/levelinfo.conf" ]; then
        if [ -f "$path/levelinfo.conf.bak" ]; then
          mv "$path/levelinfo.conf.bak" "$path/levelinfo.conf"
        else
          # there isn't any; try to make a new one
          make_group_levelinfo "$path/levelinfo.conf" "${path#$levels/}"
        fi
      fi
    fi
  done
}

function update_packages () { # args: directory
  ## searches for new packages in the directory, and if it founds one,
  ## creates a symlink to it in the level structure
  for path in `find "$1" -mindepth 1 -maxdepth 1 -type d`; do
    local package="${path#$1/}"
    
    # is it a valid package?
    [ -e "$path/rlm.conf" ] || continue
    
    levelsets="$levelsets$newline$package"
    
    # first check if there's already one
    [ -z "`find "$levels" -name "$package"`" ] || continue
    
    # make a symlink
    config_open "$path/rlm.conf"
    config_get_value "levelgroup"
    local levelgroup="$value"
    # example levelgroup: "/Contributions/Contributions 2003"
    if [ ! -e "$levels$levelgroup/$package" ]; then
      [ -d "$levels$levelgroup" ] || make_levelgroup "$levelgroup"
      ln -s "$path" "$levels$levelgroup/$package"
    fi
    config_close
  done
}

function update_packages_everywhere () {
  levelsets=''
  [ -d "$packages" ]        && update_packages "$packages"
  [ -d "$packages_global" ] && update_packages "$packages_global"
  [ -d "$packages_shared" ] && update_packages "$packages_shared"
}


