#!/bin/bash
#set -n		# read but do not execute commands (check on syntax errors)
#
# File: /usr/local/bin/camp
#
# CAMP (Contol file Assisted Media Player) using DIALOG.
#
#    Copyright (c) 2016  Juergen Kaesmann (JK)
#
##############################################################################
# GPL NOTICE
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
##############################################################################
# FIND SAMPLES
#
##############################################################################
# FILTER SAMPLES
#
##############################################################################
# AWK SAMPLES
#
##############################################################################
# SED SAMPLES
#
##############################################################################
# XARGS
#
##############################################################################
# REPLACE STRINGS
#
##############################################################################
# RSYNC OPTIONS
#
##############################################################################
# DIALOG SAMPLES
#
# Given/selected answer goes to STDERR
#
# if list-height|form-height|menu-height used then:
# set lh|fh|mh=h-7
# Optimum for a standard 25x80 terminal h w lh|fh|mh: 25 80 18
# For automatic size set h w lh fh mh to 0
#
# buildlist: display 2 lists side-by-side,move items between,h w lh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --visit-items --buildlist "$wtitle" height width list-height [ tag item status ] ... 2>$ansfile
#
# calendar: display and edit a date, h w = 15 60
#dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --calendar "$wtitle" height width day month year 2>$ansfile
#
# checklist: show a list with (de)selectable entries, h w lh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --no-tags --checklist "$wtitle" height width list-height [tag item status] ... 2>$ansfile
#
# dselect: display and input a directory, lh w = 15 80
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --dselect filepath list-height width 2>$ansfile
#
# editbox: display and edit a file, h w = 25 80
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --editbox filepath height width 2>$ansfile
#
# form: show a formula with editable entries, h w fh = 25 80 18, x,y count from top,left, flen(fieldlen)=0|-len ilen(inputlen)=0|len, FixFields=-flen
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --form "$wtitle" height width form-height [ label y x item y x flen ilen ] ... 2>$ansfile
#
# fselect: show a file selection box, lh w = 15 80
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --fselect filepath list-height width 2>$ansfile
#
# gauge: display a meter, h w = 15 60
#dialog --title "$dtitle" --no-shadow --gauge "$wtitle" height width [percent]
#
# infobox: display a msg and exit, h w = 5 60
#dialog --title "$dtitle" --ok-label "Ok" --no-shadow --infobox "$wtitle" height width
#
# inputbox: show a msg, input an ans, h w = 8 60
#dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --inputbox "$text" height width ["$init"] 2>$ansfile
#
# inputmenu: like menu but with button RENAME to rename one of the entries, h w mh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --inputmenu "$wtitle" height width menu-height [ tag item ] ... 2>$ansfile
#
# menu: show a menu, h w mh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --no-tags --menu "$wtitle" height width menu-height [tag item] ... 2>$ansfile
#
# mixedform: like form but with field-type each, h w fh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --mixedform "$wtitle" height width formheight [ label y x item y x flen ilen itype ] ... 2>$ansfile
#
# mixedgauge: like gauge but with tag item pairs, h w = 15 60
#dialog --title "$dtitle" --no-shadow --mixedgauge "$wtitle" height width percent [ tag1 item1 ] ...
#
# msgbox: show a msg, h w = 7 60
#dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" height width
#
# passwordbox: like inputbox with invisible input, h w = 8 60
#dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --passwordbox "$wtitle" height width [init] 2>$ansfile
#
# passwordform: like form but with all fields are password widgets, h w fh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --passwordform "$wtitle" height width form-height [ label y x item y x flen ilen ] ... 2>$ansfile
#
# pause: display seconds to remain, h w = 8 39
#dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --pause "$wtitle" height width seconds
#
# prgbox: display output of command and enable to quit, h w = 25 80
#dialog --title "$dtitle" --no-shadow --prgbox ["$wtitle"] command height width
#
# programbox: display piped output of command with button OK, h w = 25 80
#dialog --title "$dtitle" --ok-label "Ok" --no-shadow --programbox "$wtitle" [text] height width
#
# progressbox: display piped output of command, no button, h w = 25 80
#dialog --title "$dtitle" --no-shadow --progressbox ["$wtitle"] height width
#
# radiolist: select one status to ON, h w lh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --radiolist "$wtitle" height width list-height [ tag item status ] ... 2>$ansfile
#
# rangebox: select with slider from a range of values, h w lh =25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --rangebox "$wtitle" height width list-height min-value max-value default-value 2>$ansfile
#
# tailbox: display text from a file like 'tail -f', h w = 25 80
#dialog --title "$dtitle" --ok-label "Ok" --no-shadow --tailbox "$file" height width
#
# tailboxbg: display text from a file like 'tail -f' in the background, h w = 25 80
#dialog --title "$dtitle" --no-shadow --tailboxbg "$file" height width
#
# textbox: show a file's content, h w = 25 80
#dialog --title "$dtitle" --no-shadow --tab-correct --textbox "$file" height width
#
# timebox: display and edit a time, h w = 3 39
#dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --timebox "$wtitle" height width [ hour minute second ] 2>$ansfile
#
# treeview: display tree data and select one of them, h w lh = 25 80 18
#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --treeview "$wtitle" height width list-height [ tag item status depth ] ... 2>$ansfile
#
# yesno: show a msg, select yes or no, h w = 6 60, Ret 0=yes 1=no other=cancel
#dialog --title "$dtitle" --no-shadow --yesno "$question\nOverwrite?" height width
#
##############################################################################
# EXIT CODES

##############################################################################
# SOURCE FILES
#
. /usr/local/etc/main.conf				# config main
#. $LLIBDIR/libfuncerr-sh				# functions error
. $LLIBDIR/libfuncstd-sh				# functions standard
#. $LLIBDIR/libfuncmath-sh				# functions math
#. $LLIBDIR/libfuncmath2-sh				# functions math2
#. $LLIBDIR/libfuncip-sh				# functions IP
. /usr/local/etc/camp.conf				# config camp
#
#if [ ! -e ~/.samplerc ]; then				# install config user
#	cp /usr/local/share/ksm-sample/samplerc ~/.samplerc
#fi
#. ~/.samplerc						# config user

##############################################################################
# DECLARATION OF STANDARD CONSTANTS AND VARIABLES
#
readonly package=CAMP					# package name
readonly package_file=ksm-camp				# package file name
readonly vinfopath="/usr/local/share/$package_file"	# path to package dir
readonly version=$(/bin/cat $vinfopath/VERSION)		# package version
readonly release=$(/bin/cat $vinfopath/RELEASE)		# package release
readonly scriptname=$(basename $0)			# name of script
#readonly tempfile=$TEMPDIR/$scriptname.$UID.tmp	# temporary file name
tempfile=$(mktemp -u $TEMPDIR/$scriptname.$UID.XXXXXX)	# temporary file name
readonly lockfile=$TEMPDIR/lock/$scriptname.$UID.lock	# lock file name
readonly debuglog="/usr/bin/logger -p user.debug -t $scriptname -- DEBUG:"	# log dbg msg
readonly errlog="/usr/bin/logger -p user.err -t $scriptname -- ERROR:"		# log err msg
readonly infolog="/usr/bin/logger -p user.info -t $scriptname -- INFO:"		# log inf msg
cmd=''							# sub command
debug=no						# debug=yes/no
verbose=''						# verbose=yes/''/no
err=0							# error code

##############################################################################
# USER FILL IN AT FIRST RUN

##############################################################################
# SYSTEM

##############################################################################
# VLC
#
readonly xml_version='<?xml version="1.0" encoding="UTF-8"?>'
readonly xml_playlist='<playlist version="1" xmlns="http://xspf.org/ns/0/" xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/">'
readonly xml_playlist_end='</playlist>'
readonly xml_tracklist='<trackList>'
readonly xml_tracklist_end='</trackList>'
readonly xml_track='<track>'
readonly xml_track_end='</track>'
readonly xml_title='<title>'
readonly xml_title_end='</title>'
readonly xml_location='<location>'
readonly xml_location_end='</location>'
readonly xml_extension_vlc='<extension application="http://www.videolan.org/vlc/playlist/0">'
readonly xml_extension_end='</extension>'
readonly xml_vlc_id='<vlc:id>'
readonly xml_vlc_id_end='</vlc:id>'
readonly xml_vlc_option='<vlc:option>'
readonly xml_vlc_option_end='</vlc:option>'
readonly xml_vlc_item='<vlc:item tid="'
readonly xml_vlc_item_end='"/>'

##############################################################################
# USER-CONSTANTS
#
# STRINGS
#readonly const=string
readonly wluext="wlu"					# ext.for wave playlist

# NUMBERS
#readonly const=value

##############################################################################
# USER-VARIABLES
#
# STRINGS
# Variables from camp.conf
# APLAYER
# APLAYER_QUIT
# DVDPLAYER
# VPLAYER
# VPLAYER_QUIT
# WPLAYER

tempfile2=$(mktemp -u $TEMPDIR/$scriptname.$UID.XXXXXX)	# temporary file name
ansfile=$(mktemp -u $TEMPDIR/$scriptname.$UID.ans.XXXXXX) # dialog output
chpfile=$(mktemp -u $TEMPDIR/$scriptname.$UID.XXXXXX)	# file for chapter list
playlist=$(mktemp -u $TEMPDIR/$scriptname.$UID.XXXXXX)	# temporary file name
playlist="${playlist}.xspf"

#args=''				# all args from cmdline
#arg1=''				# 1. arg from cmdline
#opt_o=''				# option -o (yes)
					# option --output (yes)
#opt_i=''				# option -i (arg)
					# option --infile (arg)
#opt_o=''				# option -o (arg)
					# option --outfile (arg)
#opt_p=''				# option -p (arg)
					# option --pages (arg)
startdir="/"				# path for init open file dialog
wluall=no

# NUMBERS
#p_first=0				# first page
#p_last=0				# last page
dialog_h=0				# actual screen height
dialog_w=0				# actual screen width
maxCHAPTER=0
maxTRACK=0
maxoptarr=0

# ARRAYS
# Indexed arrays are always zero based string arrays.
# If index starts with 1 and all members are assigned then
# count of members of array = last index of array
#declare -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array

#declare -a CHAPTER			# chapter info from mcf
#maxCHAPTER="${#CHAPTER[@]}"		# get number of elements in arr
#unset CHAPTER[@]			# remove the entire array

#declare -a TRACK			# track info from mcf
#maxTRACK="${#TRACK[@]}"		# get number of elements in arr
#unset TRACK[@]				# remove the entire array

declare -a optarr			# chapter options from mcf
#maxoptarr="${#optarr[@]}"		# get number of elements in arr
#unset optarr[@]			# remove the entire array

##############################################################################
# LANGUAGE SUPPORT

##############################################################################
# SIGNAL HANDLING

##############################################################################
# FUNCTIONS
##############################################################################
#
##############################################################################
# HELP
#
#=============================================================================
function helptext ()
{
# Output helptext
# Uses cat, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG helptext: $# $@" >&2
	$debuglog helptext: $# $@
fi

cat <<EOT
NAME
$scriptname - CAMP (Control-file Assisted Media Player) using DIALOG.

SYNOPSIS
$scriptname [options]

DESCRIPTION
CAMP (Control-file Assisted Media Player) using DIALOG. This is a
version which uses Text Graphic. But running in a console under X (KDE)
you can use the mouse too.

The player has seven functions:

  1. Play medias controlled by a media control file (.mcf).

  2. Play immediate the selected media.

  3. Play a media playlist (.xspf).

  4. Play an mp3 playlist (.m3u).

  5. Play a wav playlist (.${wluext}). A .$wluext file is like an .m3u
     file, but it contains pathnames of wav files.

  6. Show a text file (.txt) or a file with info about volume
     processing (.volume).

  7. Show an image file. If your viewer understand .jpg or .png.

If a dvd directory is detected then xine is used to play the DVD, else
we use vlc per default.

Advanced users can change all players and viewers by editing the file
/usr/local/etc/camp.conf (VPLAYER DVDPLAYER APLAYER WPLAYER IVIEWER).

Defaults:

  if the selected file is an mcf then
    if the selected file belongs to a dvd then
      play the dvd
    else
      show media info from mcf and wait to play all up from the
      selected entry
  else if the selected file is an m3u then
    show media info from m3u and wait to play all up from the selected
    entry
  else if the selected file is an $wluext then
    show media info from $wluext and wait to play all up from the
    selected entry
  else if the selected file is a text file (.txt or .volume) then
    show the selected text file
  else if the selected file is an image (.jpg or .png) then
    show the selected image file
  else
    if possible then play the selected media file or xspf.

OPTIONS
Gnu style options:

  -h|--help    = Output help, then exit.
  -V|--version = Output version info, then exit.
  -d|--debug   = Turn on DEBUG mode.
  -f           = Open the file menu at start. If quit then exit.
  --           = End of options.

EXIT STATUS
On program exit:

  Code 0 = OK

  See output of 'showerrmsg'.

FILES
Used directories and files:

  Config Global = /usr/local/etc/camp.conf

SEE ALSO
Related manpages:

  showerrmsg(1), makemcf(1), vlc(1), xine(1), jomp(1), play(1), xli(1).

AUTHORS
Juergen Kaesmann <juergen@kaesmann-online.de>
EOT
#  -q|--quiet   = Be quiet.
#  -v|--verbose = Be verbose.
#  -o|--output  = Output to STDOUT.
#  -i f         = Input from file <f>.
#  --infile=f   = Input from file <f>.
#  -o f         = Output to file <f>.
#  --outfile=f  = Output to file <f>.
#  -p s,e       = Pages s=START e=END.
#  --pages=s,e  = Pages s=START e=END.

#ARGUMENTS
#Give if needed:
#
#  file = Media Control File (.mcf) or a media file.

#EXAMPLES
#For instance:
#
#  Do it:
#  $scriptname

return
}

#=============================================================================
function init_dialog ()
{
# Get dialog values for sizing.
# par1 = 
# Uses echo, logger
# Uses global vars: dialog_h dialog_w
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG init_dialog: $# $@" >&2
	$debuglog init_dialog: $# $@
fi

local dialog_size=''			# actual screen size (text)
local dialog_numbers=''			# number part from dialog_size (text)
local ret=0

dialog_size=$(dialog --stdout --print-maxsize)
dialog_numbers=$(echo $dialog_size | cut -d ':' -f2 | tr -d ' ')
dialog_h=$(echo "$dialog_numbers" | cut -d ',' -f1)
dialog_w=$(echo "$dialog_numbers" | cut -d ',' -f2)

return $ret
}

#=============================================================================
function show_about ()
{
# Show info about program.
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG show_about: $# $@" >&2
	$debuglog show_about: $# $@
fi

local dtitle='' msgtxt=''
local prog="CAMP"
local vr="Version ${version}-${release}"
local auth="by Juergen Kaesmann"
local ret=0

CSet 28 "$prog"
ret=$?
if [ $ret -eq 0 ]; then Pop prog; fi

CSet 28 "$vr"
ret=$?
if [ $ret -eq 0 ]; then Pop vr; fi

CSet 28 "$auth"
ret=$?
if [ $ret -eq 0 ]; then Pop auth; fi

msgtxt="
$prog

$vr

$auth"

# msgbox: show a msg, h w = 5 60
#dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" height width
dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" 11 32
ret=$?

return $ret
}

#=============================================================================
function show_msg ()
{
# Show a msg text.
# par1 = msgtxt
# Uses dialog, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG show_msg: $# $@" >&2
	$debuglog show_msg: $# $@
fi

local dtitle="MESSAGE" msgtxt="$1"
local ret=0

# msgbox: show a msg, h w = 7 60
#dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" height width
dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" 7 60
ret=$?

return $ret
}

#=============================================================================
function show_error ()
{
# Show the error text.
# par1 = errcode
# par2 = additional errtext
# Uses dialog, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG show_error: $# $@" >&2
	$debuglog show_error: $# $@
fi

local dtitle='ERROR' msgtxt="\Z1${ErrMsg[$1]}\Zn $2"
local ret=0

# msgbox: show a msg, h w = 7 60
#dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" height width
dialog --title "$dtitle" --no-shadow --colors --msgbox "$msgtxt" 7 60
ret=$?

return $ret
}

#=============================================================================
function show_debug ()
{
# Show a msg text.
# par1 = msgtxt
# Uses dialog, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG show_debug: $# $@" >&2
	$debuglog show_debug: $# $@
fi

local dtitle="DEBUG" msgtxt="$1"
local ret=0

# msgbox: show a msg, h w = 25 80
#dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" height width
dialog --title "$dtitle" --no-shadow --msgbox "$msgtxt" 0 0
ret=$?

return $ret
}

#=============================================================================
function show_info ()
{
# Show an info and exit.
# par1 = msgtxt
# Uses dialog, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG show_info: $# $@" >&2
	$debuglog show_info: $# $@
fi

local dtitle="INFO" wtitle="$1"
local ret=0

# infobox: display a msg and exit, h w = 7 60
#dialog --title "$dtitle" --ok-label "Ok" --no-shadow --infobox "$wtitle" height width
dialog --title "$dtitle" --no-shadow --infobox "$wtitle" 7 60
ret=$?

return $ret
}

#=============================================================================
function show_textfile ()
{
# Show content of a text file.
# par1 = dtitle
# par2 = filename
# Uses dialog, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG show_textfile: $# $@" >&2
	$debuglog show_textfile: $# $@
fi

local dtitle="$1" file="$2"
local ret=0

# textbox: show a file's content, h w = 25 80
#dialog --title "$dtitle" --no-shadow --tab-correct --textbox "$file" height width
dialog --title "$dtitle" --no-shadow --tab-correct --scrollbar --textbox "$file" 0 0
ret=$?

return $ret
}

#=============================================================================
function pause ()
{
# Make a Pause.
# par1 = wtitle
# par2 = Seconds to pause
# Uses dialog, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG pause: $# $@" >&2
	$debuglog pause: $# $@
fi

local dtitle="PAUSE" wtitle="$1" s="$2"
local ret=0

# pause: display seconds to remain, h w = 8 39
#dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --pause "$wtitle" height width seconds
dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --pause "$wtitle" 8 39 $s
ret=$?

return $ret
}

#=============================================================================
function get_input ()
{
# Get input from user.
# par1 = text
# par2 = value (startvalue)
# Push result onto stack (1 string).
# Uses global ansfile
# Uses cat, dialog, logger, rm
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG get_input: $# $@" >&2
	$debuglog get_input: $# $@
fi

local dtitle="INPUT" txt="$1" val="$2" s=''
local ret=0

if [ -z "$3" ]; then					# parameter count ok
	# inputbox: show a msg, input an ans, h w = 8 60
	#dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --inputbox "$text" height width ["$init"] 2>$ansfile
	dialog --title "$dtitle" --ok-label "Ok" --cancel-label "Cancel" --no-shadow --inputbox "$txt" 8 60 "$val" 2>$ansfile
	ret=$?
	if [ "$ret" -eq 0 ]; then
		s=$(cat $ansfile)
		if [ -n "$s" ]; then
			Push "$s"
		else
			ret=10
		fi
	fi
	rm -f $ansfile
else
	show_error 2 "in get_input"
	ret=2
fi

return $ret
}

#=============================================================================
function get_yesno ()
{
# Get a yes/no answer from user.
# par1 = text
# Uses global ansfile
# Uses dialog, logger, rm
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG get_yesno: $# $@" >&2
	$debuglog get_yesno: $# $@
fi

local dtitle="YES or NO" txt="$1"
local ret=0

# yesno: show a msg, select yes or no, h w = 6 60, Ret 0=yes 1=no other=cancel
#dialog --title "$dtitle" --no-shadow --yesno "$question\nOverwrite?" height width
dialog --title "$dtitle" --no-shadow --yesno "$txt" 6 60
ret=$?
rm -f $ansfile

return $ret
}

#=============================================================================
function build_chapterfile ()
{
# Build chapter list or track list.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG build_chapterfile: $# $@" >&2
	$debuglog build_chapterfile: $# $@
fi

local dtitle='ERROR' medium='' txt='' msgtxt=''
local i=0 ret=0
# NO-BREAK SPACE = ' '

rm -f $chpfile
case "$MTYPE" in
    VIDEO)
	maxCHAPTER="${#CHAPTER[@]}"
	i=0
	while [ $i -lt $maxCHAPTER ]; do
		let ++i
		txt=$(echo "${CHAPTER[$i]}" | cut -f 3)
		txt=${txt// / }		# replace SPACE with NO-BREAK SPACE
		echo "${i} ${txt}" >> $chpfile
		ret=$?
	done
	;;
    AUDIO)
	maxTRACK="${#TRACK[@]}"
	i=0
	while [ $i -lt $maxTRACK ]; do
		let ++i
		medium=$(echo "${TRACK[$i]}")
		echo "$i	$medium" >> $chpfile
		ret=$?
	done
	;;
    *)
	show_error 1 "Mediatype $MTYPE not supported."
	ret=1
	;;
esac

return $ret
}

#=============================================================================
function count_tabs ()
{
# Count the TABs in String.
# Values are transferred to and from this function via given variable names.
# Additional normal values can be supplied.
# Local variables should surrounded by _  ( ret --> _ret_ ).
# Call: count_tabs mytransfer $searchstr
#
# We use 1 returned value in its transfer variable:
# par1 = name of transfer variable (content = count of TABs)
# par2 = string to search in
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG count_tabs: $# $@" >&2
	$debuglog count_tabs: $# $@
fi

#	n=name			v=value
local count_tabs_n1="$1" count_tabs_v1="${!1}"
local _s_="$2"
local _c_=0 _i_=0 _n_=0 _ret_=0

# do the stuff
_n_=${#_s_}
_c_=0
_i_=0
while [ ${_i_} -lt ${_n_} ]; do
	if [ "${_s_:$_i_:1}" == "	" ]; then
		let ++_c_
	fi
	let ++_i_
done
_ret_=$?

# return values
eval ${count_tabs_n1}="\"${_c_}\""

return ${_ret_}
}

#=============================================================================
function start_playlist ()
{
# Write start statements to file $playlist
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG start_playlist: $# $@" >&2
	$debuglog start_playlist: $# $@
fi

local ret=0

echo "${xml_version}" >> $playlist
echo "${xml_playlist}" >> $playlist
echo "${xml_title}Playlist${xml_title_end}" >> $playlist
echo "${xml_tracklist}" >> $playlist
ret=$?

return $ret
}

#=============================================================================
function add_playlist ()
{
# Add media to playlist (build 1 track).
# par1 = media file	path/file
# par2 = id		0 - n
# par3 = start time	secs
# All other options are hold in optarr
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG add_playlist: $# $@" >&2
	$debuglog add_playlist: $# $@
fi

local medium="$1" title=${medium##*/}
local i=0 id="$2" start="$3" ret=0

echo "${xml_track}" >> $playlist
echo "${xml_title}${title}${xml_title_end}" >> $playlist
echo "${xml_location}file://${medium}${xml_location_end}" >> $playlist
echo "${xml_extension_vlc}" >> $playlist
echo "${xml_vlc_id}${id}${xml_vlc_id_end}" >> $playlist

if [ "$start" -gt 0 ]; then
	echo "${xml_vlc_option}start-time=${start}${xml_vlc_option_end}" >> $playlist
fi

maxoptarr="${#optarr[@]}"
i=0
while [ $i -lt $maxoptarr ]; do
	let ++i
	echo "${xml_vlc_option}${optarr[$i]}${xml_vlc_option_end}" >> $playlist
done

echo "${xml_extension_end}" >> $playlist
echo "${xml_track_end}" >> $playlist

return $ret
}

#=============================================================================
function end_playlist ()
{
# Write end statements to file $playlist
# par1 = endid
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG end_playlist: $# $@" >&2
	$debuglog end_playlist: $# $@
fi

local endid="$1" i=0 ret=0

echo "${xml_tracklist_end}" >> $playlist
echo "${xml_extension_vlc}" >> $playlist

i=0
while [ $i -lt $endid ]; do
	let ++i
	echo "${xml_vlc_item}${i}${xml_vlc_item_end}" >> $playlist
done

echo "${xml_extension_end}" >> $playlist
echo "${xml_playlist_end}" >> $playlist

return $ret
}

#=============================================================================
function play_media ()
{
# Play chapters or tracks from media control file.
# par1 = start chapter or track
# Uses vlc, APLAYER, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG play_media: $# $@" >&2
	$debuglog play_media: $# $@
fi

local dtitle='ERROR'
local medium='' lastmed='' plist='' ext=''
local i="$1" j=0 id=0 start=0 optcnt=0 ret=0
#unset optarr[@]			# remove the entire array

case "$MTYPE" in
    VIDEO)						# video
	maxCHAPTER="${#CHAPTER[@]}"

	# play selected file+chapter till end of file
	medium=$(echo "${CHAPTER[$i]}" | cut -f 1)
	if [ "${medium:0:1}" == "-" ]; then
		medium=${medium:1}
	fi
	lastmed="$medium"
	start=$(echo "${CHAPTER[$i]}" | cut -f 2)
	count_tabs optcnt "${CHAPTER[$i]}"
	optcnt=$(($optcnt-2))

	j=0
	while [ $j -lt $optcnt ]; do
		let ++j
		optarr[$j]=$(echo "${CHAPTER[$i]}" | cut -f $((3+$j)))
	done

	# build vlc playlist.xspf
	id=1
	rm -f $playlist
	start_playlist
	add_playlist "$MDIR/$medium" $id "$start"
	unset optarr[@]				# remove the entire array

	# play all following media complete
	while [ $i -lt $maxCHAPTER ]; do
		let ++i
		# find next chapter and next new medium to playlist
		medium=$(echo "${CHAPTER[$i]}" | cut -f 1)
		if [ "$medium" != "$lastmed" ]; then	# new medium
			if [ "${medium:0:1}" != "-" ]; then   # real new media
				lastmed="$medium"
				count_tabs optcnt "${CHAPTER[$i]}"
				optcnt=$(($optcnt-2))

				j=0
				while [ $j -lt $optcnt ]; do
					let ++j
					optarr[$j]=$(echo "${CHAPTER[$i]}" | cut -f $((3+$j)))
				done

				let ++id
				add_playlist "$MDIR/$medium" $id 0
				unset optarr[@]		# remove the entire array
			else				# same media, prep w. -
				medium=${medium:1}
				start=$(echo "${CHAPTER[$i]}" | cut -f 2)
				count_tabs optcnt "${CHAPTER[$i]}"
				optcnt=$(($optcnt-2))

				j=0
				while [ $j -lt $optcnt ]; do
					let ++j
					optarr[$j]=$(echo "${CHAPTER[$i]}" | cut -f $((3+$j)))
				done

				let ++id
				add_playlist "$MDIR/$medium" $id "$start"
				unset optarr[@]		# remove the entire array
			fi
		fi
	done
	end_playlist $id

	# play media
	$VPLAYER $GLOBOPT $playlist $VPLAYER_QUIT
	ret=$?
	rm -f $playlist
	;;
    AUDIO)						# mp3, wav, other
	# get ext from 1. track
	ext="${TRACK[1]##*.}"
	case "$ext" in
	    mp3)
		maxTRACK="${#TRACK[@]}"
		plist=''
		let --i
		while [ $i -lt $maxTRACK ]; do
			let ++i
			medium=$(echo "${TRACK[$i]}")
			medium="$MDIR/$medium"
			plist="$plist $medium "
			ret=$?
		done
		$APLAYER $GLOBOPT $plist $APLAYER_QUIT
		;;
	    wav)
		maxTRACK="${#TRACK[@]}"
		plist=''
		let --i
		while [ $i -lt $maxTRACK ]; do
			let ++i
			medium=$(echo "${TRACK[$i]}")
			medium="$MDIR/$medium"
			plist="$plist $medium "
			ret=$?
		done
		$WPLAYER $GLOBOPT $plist
		;;
	    *)
		maxTRACK="${#TRACK[@]}"
		plist=''
		let --i
		while [ $i -lt $maxTRACK ]; do
			let ++i
			medium=$(echo "${TRACK[$i]}")
			medium="$MDIR/$medium"
			plist="$plist $medium "
			ret=$?
		done
		$VPLAYER $GLOBOPT $plist $VPLAYER_QUIT
		;;
	esac
	;;
    *)
	show_error 1 "Mediatype $MTYPE not supported."
	ret=1
	;;
esac

return $ret
}

#=============================================================================
function show_menu_play_mcf_help ()
{
# Show the menu help text.
# par1 = 
# Uses dialog, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG show_menu_play_mcf_help: $# $@" >&2
	$debuglog show_menu_play_mcf_help: $# $@
fi

local dtitle='HELP FOR MENU' msgtxt=""
local ret=0

msgtxt="Select an entry with cursor UP/DOWN then hit 'Play'."
show_msg "$msgtxt"
ret=$?

return $ret
}

#=============================================================================
function menu_select_from_mcf ()
{
# Menu to select a chapter from mcf
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG menu_select_from_mcf: $# $@" >&2
	$debuglog menu_select_from_mcf: $# $@
fi

local dtitle="$TITLE" wtitle='Select first entry to play'
local ans='' chplist='' quit=no
local w=0 ret=0

# prepare list for dialog
build_chapterfile
chplist=$(cat $chpfile)
rm -f $chpfile

while [ "$quit" != yes ]; do
	init_dialog
	if [ $dialog_w -gt 80 ]; then
		w=80
	else
		w=$dialog_w
	fi

	# menu: show a menu, h w mh = 25 80 18
	#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --no-tags --menu "$wtitle" height width menu-height [tag item] ... 2>$ansfile
	dialog --title "$dtitle" --ok-label "Play" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --scrollbar --menu "$wtitle" $dialog_h $w $[${dialog_h}-7] $chplist 2>$ansfile
	ret=$?
	ans=$(cat $ansfile)
	rm -f $ansfile
	case "$ret" in
	    0)						# Yes or OK button
		play_media $ans
		ret=$?
		#quit=yes
		;;
	    1|255)					# No or Cancel or ESC
		ret=1
		quit=yes
		;;
	    2)						# Help button
		show_menu_play_mcf_help
		ret=$?
		;;
#	    3)						# Extra button
#		menu_extra
#		ret=$?
#		quit=yes
#		;;
	    *)						# Others
		show_error 99 "From dialog $ret"
		ret=99
		quit=yes
		;;
	esac
done

return $ret
}

#=============================================================================
function show_menu_play_m3u_help ()
{
# Show the menu help text.
# par1 = 
# Uses dialog, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG show_menu_play_m3u_help: $# $@" >&2
	$debuglog show_menu_play_m3u_help: $# $@
fi

local dtitle='HELP FOR MENU' msgtxt=""
local ret=0

msgtxt="Select an entry with cursor UP/DOWN then hit 'Play'."
show_msg "$msgtxt"
ret=$?

return $ret
}

#=============================================================================
function menu_select_from_m3u ()
{
# Menu to select an m3u
# par1 = m3u file
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG menu_select_from_m3u: $# $@" >&2
	$debuglog menu_select_from_m3u: $# $@
fi

local f="$1" dtitle=$(basename $1) wtitle='Select first entry to play'
local ans='' dlist='' plist='' quit=no
local i=0 ret=0

# build complete playlist for dialog
dlist=''
i=0
while read; do
	if [ ${REPLY:0:1} != "#" ]; then
		let ++i
		dlist="$dlist $i $(basename $REPLY)"
	fi
done<$f

while [ "$quit" != yes ]; do
	init_dialog
	# menu: show a menu, h w mh = 25 80 18
	#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --no-tags --menu "$wtitle" height width menu-height [tag item] ... 2>$ansfile
	dialog --title "$dtitle" --ok-label "Play" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --scrollbar --menu "$wtitle" 0 0 0 $dlist 2>$ansfile
	ret=$?
	ans=$(cat $ansfile)
	rm -f $ansfile
	case "$ret" in
	    0)						# Yes or OK button
		plist=''
		i=0
		while read; do				# get all lines from sel to last
			if [ ${REPLY:0:1} != "#" ]; then
				let ++i
				if [ $i -ge $ans ]; then
					plist="$plist $REPLY"
				fi
			fi
		done<$f
		$APLAYER $GLOBOPT $plist $APLAYER_QUIT
		ret=$?
		#quit=yes
		;;
	    1|255)					# No or Cancel or ESC
		ret=1
		quit=yes
		;;
	    2)						# Help button
		show_menu_play_m3u_help
		ret=$?
		;;
#	    3)						# Extra button
#		menu_extra
#		ret=$?
#		quit=yes
#		;;
	    *)						# Others
		show_error 99 "From dialog $ret"
		ret=99
		quit=yes
		;;
	esac
done

return $ret
}

#=============================================================================
function show_menu_wlu_help ()
{
# Show the menu help text for wlu menu.
# par1 = 
# Uses dialog, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG show_menu_wlu_help: $# $@" >&2
	$debuglog show_menu_wlu_help: $# $@
fi

local dtitle='HELP FOR MENU' msgtxt=""
local ret=0

msgtxt="Select an entry with cursor UP/DOWN.

The standard is to play only this selected entry with $APLAYER

'All' enables playing up from selection till last item (one time).
If selected then we use $VPLAYER
After end of playing then the effect of 'All' is reverted.

Hit 'Play' to start playing."

echo "$msgtxt" > $tempfile
show_textfile "$dtitle" "$tempfile"
ret=$?
rm -f $tempfile

return $ret
}

#=============================================================================
function menu_select_from_wlu ()
{
# Menu to select a wlu
# par1 = m3u file
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG menu_select_from_wlu: $# $@" >&2
	$debuglog menu_select_from_wlu: $# $@
fi

local f="$1" dtitle=$(basename $1) wtitle='Select entry to play'
local ans='' dlist='' plist='' quit=no
local i=0 ret=0

# build complete playlist for dialog
dlist=''
i=0
while read; do
	let ++i
	dlist="$dlist $i $(basename $REPLY)"
done<$f

while [ "$quit" != yes ]; do
	init_dialog
	# menu: show a menu, h w mh = 25 80 18
	#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --no-tags --menu "$wtitle" height width menu-height [tag item] ... 2>$ansfile
	dialog --title "$dtitle" --ok-label "Play" --extra-button --extra-label "All" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --scrollbar --menu "$wtitle" 0 0 0 $dlist 2>$ansfile
	ret=$?
	ans=$(cat $ansfile)
	rm -f $ansfile
	case "$ret" in
	    0)						# Yes or OK button
		plist=''
		i=0
		while read; do				# get all lines from sel till last
			let ++i
			if [ "$wluall" == no ]; then
				if [ $i -eq $ans ]; then
					plist="$REPLY"
				fi
			else
				if [ $i -ge $ans ]; then
					plist="$plist $REPLY"
				fi
			fi
		done<$f
		if [ "$wluall" == no ]; then
			$WPLAYER $plist &>/dev/null
			ret=$?
		else
			$VPLAYER $plist &>/dev/null
			ret=$?
			wluall=no
		fi
		#quit=yes
		;;
	    1|255)					# No or Cancel or ESC
		ret=1
		quit=yes
		;;
	    2)						# Help button
		show_menu_wlu_help
		ret=$?
		;;
	    3)						# Extra button
		#menu_extra
		wluall=yes
		ret=$?
		#quit=yes
		;;
	    *)						# Others
		show_error 99 "From dialog $ret"
		ret=99
		quit=yes
		;;
	esac
done
wluall=no

return $ret
}

#=============================================================================
function check_dirparts ()
{
# Check and report the deep (parts) of a dir.
# par1 = dir
# Uses echo, logger
# If OK then Push parts onto stack.
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG check_dirparts: $# $@" >&2
	$debuglog check_dirparts: $# $@
fi

local d="$1" s=''
local i=0 l=0 n=0 ret=0

# rem last /
l=${#d}
let --l
s=${d:$l:1}
if [ "$s" == / ]; then
	d=${d:0:$l}
	ret=$?
fi

# count /
n=0
i=0
while [ $i -lt $l ]; do
	if [ ${d:$i:1} == / ]; then
		let ++n
	fi
	let ++i
done
ret=$?

# push result onto stack
if [ $ret -eq 0 ]; then
	Push "$n"
fi

return $ret
}

#=============================================================================
function fselect_ok ()
{
# Handle file name and do action.
# par1 = Pathname of Media Control File or m3u file or media file
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG fselect_ok: $# $@" >&2
	$debuglog fselect_ok: $# $@
fi

local f="$1" ext='' plist=''
local ret=0

ext="${f##*.}"
case "$ext" in
    txt|volume)
	show_textfile "TEXTFILE" "$f"
	ret=$?
	;;
    mcf)
	unset CHAPTER[@]				# remove the entire array
	unset TRACK[@]					# remove the entire array
	source $f
	if $(echo "$MDIR" | grep -q VIDEO_TS); then	# DVD
		$DVDPLAYER $GLOBOPT dvd://$MDIR
		ret=$?
	else
		menu_select_from_mcf
	fi
	;;
    m3u)
	menu_select_from_m3u "$f"
	ret=$?
	;;
    ${wluext})
	menu_select_from_wlu "$f"
	ret=$?
	;;
    mp3)
	$APLAYER "$f" $APLAYER_QUIT
	ret=$?
	;;
    wav)
	$WPLAYER "$f" &>/dev/null
	ret=$?
	;;
    jpg|png)
	$IVIEWER "$f" &>/dev/null
	ret=$?
	;;
    *)
	$VPLAYER "$f" $VPLAYER_QUIT
	ret=$?
	;;
esac

return $ret
}

#=============================================================================
function fselect_extra ()
{
# Do extra things.
# par1 = dir
# Uses dialog, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG fselect_extra: $# $@" >&2
	$debuglog fselect_extra: $# $@
fi

#local dtitle='INFO' msgtxt="fselect_extra"
local ans="$1" dtitle="TREE"
local n=0 ret=0

check_dirparts "$ans"
ret=$?
if [ $ret -eq 0 ]; then
	Pop n
	ret=$?
	if [ "$n" -ge 3 ]; then
		# build tree from ans
		tree $ans > $tempfile
		ret=$?
	else
		ls $ans > $tempfile
		ret=$?
	fi
else
	show_error 1 "check_dirparts reports error $ret"
	ret=1
fi

if [ $ret -eq 0 ]; then
	show_textfile "$dtitle" "$tempfile"
fi
rm -f $tempfile

return $ret
}

#=============================================================================
function fselect_help ()
{
# Show the fselect help text.
# par1 = 
# Uses dialog, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG fselect_help: $# $@" >&2
	$debuglog fselect_help: $# $@
fi

local dtitle='HELP FOR FSELECT' msgtxt=""
local ret=0

msgtxt="The screen is divided into 4 areas.

+---------------------------------++---------------------------------+
|                                 ||                                 |
|       Directory window          ||          Files window           |
|                                 ||                                 |
|                                 ||                                 |
|                                 ||                                 |
|                                 ||                                 |
|                                 ||                                 |
|                                 ||                                 |
|                                 ||                                 |
|                                 ||                                 |
|                                 ||                                 |
+---------------------------------++---------------------------------+
|  Input line                                                        |
+--------------------------------------------------------------------+
|                            Button area                             |
+--------------------------------------------------------------------+

Moving between the 4 areas is done by UP DN LEFT RIGHT HOME END.

The main thing is the input line.
Dir/File selection is only done from the input line.
It exist a line completion function. Enter the beginning of a dir/file
and hit SPACE. The input line will be completed if possible.

To enter a dir name use one of the following ways:
a) Go to the directory window, select your directory then hit SPACE.
   The directory will appear in the input line and the cursor is 
   positioned at the directory name.
b) From the input line enter a directory name or at least the first few 
   characters and hit SPACE. The input line will be completed if possible.

To enter a file name use one of the following ways:
a) Go to the file window, select your file then hit SPACE.
   The file will appear in the input line and the cursor is positioned 
   at the file name.
b) From the input line enter a file name or at least the first few 
   characters and hit SPACE. The input line will be completed if possible."

echo "$msgtxt" > $tempfile
show_textfile "$dtitle" "$tempfile"
ret=$?
rm -f $tempfile

return $ret
}

#=============================================================================
function fselect_dialog ()
{
# List all dirs and files and select one file or a dir
# par1 = dtitle
# par2 = startdir
# Uses globals ansfile, startdir
# Uses cat, dialog, echo, logger, rm
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG fselect_dialog: $# $@" >&2
	$debuglog fselect_dialog: $# $@
fi

local dtitle="$1"
local ans='' quit=no
local ret=0
startdir="$2"
#show_debug "$dtitle - $startd"

while [ "$quit" != yes ]; do
	init_dialog
	# fselect: show a file selection box, lh w = 15 80
	#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --fselect filepath list-height width 2>$ansfile
	dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Tree" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --scrollbar --fselect $startdir $[${dialog_h}-10] $dialog_w 2>$ansfile
	ret=$?
	ans=$(cat $ansfile)
	rm -f $ansfile
	case "$ret" in
	    0)						# Yes or OK button
		fselect_ok "$ans"
		#startd=${ans}
		startdir=$(dirname ${ans})
		ret=$?
		#quit=yes
		;;
	    1|255)					# No or Cancel or ESC
		ret=1
		quit=yes
		;;
	    2)						# Help button
		startdir=${ans}
		fselect_help
		ret=$?
		;;
	    3)						# Extra button
		startdir=${ans}
		fselect_extra "$ans"
		ret=$?
		#quit=yes
		;;
	    *)						# Others
		show_error 99 "From dialog = $ret"
		ret=99
		quit=yes
		;;
	esac
done

return $ret
}

#=============================================================================
function menu_ok ()
{
# Do menu things.
# par1 = menu number
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG menu_ok: $# $@" >&2
	$debuglog menu_ok: $# $@
fi

local ans="$1"
local ret=0

case "$ans" in
    1)
	fselect_dialog "SELECT FILE" "$startdir"
	;;
    2)
	show_about
	;;
    *)
	;;
esac
ret=$?

return $ret
}

#=============================================================================
function menu_extra ()
{
# Do extra things. Show the helptext.
# par1 = menu number
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG menu_extra: $# $@" >&2
	$debuglog menu_extra: $# $@
fi

local dtitle='MANPAGE' ans="$1"
local ret=0

#show_msg "menu_extra: Extra Button pressed, ans=$ans"

helptext > $tempfile
show_textfile "$dtitle" $tempfile
ret=$?
rm -f $tempfile

return $ret
}

#=============================================================================
function menu_help ()
{
# Show the menu help text.
# par1 = 
# Uses dialog, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG menu_help: $# $@" >&2
	$debuglog menu_help: $# $@
fi

local dtitle='HELP FOR MENU' msgtxt=""
local ret=0

msgtxt="Select an entry with UP/DOWN then hit OK

ENTRY                  MEANING
---------------------------------------------------
Open File Menu         Select a file for processing
About CAMP             Show Info about CAMP"

echo "$msgtxt" > $tempfile
show_textfile "$dtitle" "$tempfile"
ret=$?
rm -f $tempfile

return $ret
}

#=============================================================================
function mainproc ()
{
# Show a menu with dialog.
# par1 = 
# Uses global ansfile
# Uses cat, dialog, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	#echo "DEBUG mainproc: $# $@" >&2
	$debuglog mainproc: $# $@
fi

local dtitle='MAIN MENU' wtitle='Select a menu entry'
local ans='' quit=no
local ti_list=''
local w=0 ret=0
#local -a arr
#local maxarr="${#arr[@]}"		# get number of elements in arr
#unset arr[@]				# remove the entire array

# NO-BREAK SPACE = ' '
# [tag item] ...				separate with TAB or NL
ti_list="1 Open File Menu
2 About CAMP"

while [ "$quit" != yes ]; do
	init_dialog
	if [ $dialog_w -gt 60 ]; then
		w=60
	else
		w=$dialog_w
	fi

	# menu: show a menu, h w mh = 25 80 18
	#dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Extra" --cancel-label "Cancel" --help-button --help-label "Help" --no-shadow --menu "$wtitle" height width menu-height [tag item] ... 2>$ansfile
	dialog --title "$dtitle" --ok-label "Ok" --extra-button --extra-label "Man" --cancel-label "Quit" --help-button --help-label "Help" --no-shadow --no-tags --scrollbar --menu "$wtitle" 9 $w 2 $ti_list 2>$ansfile
	ret=$?
	ans=$(cat $ansfile)
	rm -f $ansfile
	case "$ret" in
	    0)						# Yes or OK button
		menu_ok "$ans"
		ret=$?
		#quit=yes
		;;
	    1|255)					# No or Cancel or ESC
		ret=1
		quit=yes
		;;
	    2)						# Help button
		menu_help
		ret=$?
		;;
	    3)						# Extra button
		menu_extra "$ans"
		ret=$?
		#quit=yes
		;;
	    *)						# Others
		show_error 99 "From dialog = $ret"
		ret=99
		quit=yes
		;;
	esac
done
clear

return $ret
}

##############################################################################
# GET OPTIONS
##############################################################################
# Give 2 strings and all cmdline_args to function GetOpt
# (POSIX_options Gnu_long_options cmdline_args):
# GetOpt 'hVdqvi:m:' 'help version debug quiet verbose infile= myval=' $@
#
# A ':' after a POSIX option means this option needs an arg.
# A '=' after a Gnu long option means this option needs an arg.
#
# All cmd/options have to be initialised to ''!
#
# POSIX options are classified in 2 categories:
#   a) cmds (mutually exclusive). All cmds are given to var 'cmd'.
#   b) options (as many as you like). Each option is given to it's own var.
# As a general rule: If cmds/options are given multiple then last given wins.
#
# Options can take 1 argument (no whitespace in arg). If you want to give more
# than 1 arg or want to use multiple strings as 1 arg then concatenate them
# together with a delimiter like ',' or ';' or '.'
# Use a delimiter which will not be part of the arg:
# sampleprog -m val1,val2
# sampleprog --myval=val1,val2
# It's at the programmers responsibility to do meaningfull things with the
# content of the options.
#
# If err != 0 then all args are processed, else continue to look for options.
# When GetOpt finishes then all options are removed from cmdline.
#
if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG Parse Commandline: $# $@" >&2
	$debuglog Parse Commandline: $# $@
fi
#
err=0
while [ "$err" -eq 0 ]; do
	GetOpt 'hVdf' 'help version debug' $@
	err=$?
	#echo "DEBUG GET OPTIONS: err=${err}  _OPTNAME_=${_OPTNAME_}  _OPTVAL_=${_OPTVAL_}  _OPTPOS_=${_OPTPOS_}  _OPTIDX_=${_OPTIDX_}" >&2
	if [ $err -eq 0 ]; then
		case "$_OPTNAME_" in
		    h|help)	cmd="-h";;
		    V|version)	cmd="-V";;
		    f)		cmd="-${_OPTNAME_}";;
		    d|debug)	debug=yes;;
#		    q|quiet)	verbose=no;;
#		    v|verbose)	verbose=yes;;
#		    o|output)	opt_o=yes;;
#		    i|infile)	opt_i="${_OPTVAL_}";;
#		    p|pages)	opt_p="${_OPTVAL_}";;
		    --)		break;;
		    :)	Show_Err ${_ERR_MISSING_ARG_FOR_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_MISSING_ARG_FOR_OPT_};;
		    ?)	Show_Err ${_ERR_UNKNOWN_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_OPT_};;
		    *)	Show_Err ${_ERR_UNKNOWN_ERR_} "_OPTNAME_=${_OPTNAME_} _OPTVAL_=${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_ERR_};;
		esac
	fi
done
err=0
shift ${_OPTIDX_}				# rm all opts from cmdline
#
# Uncomment if giving a cmd is mandatory
#if [ -z "$cmd" ]; then					# error no cmd given
#	Show_Err 7 ""
#	exit 7
#fi

##############################################################################
# CHECK LINK NAMES

##############################################################################
# CHECK OPTIONS

##############################################################################
# CHECK VERSION
#
# check version of config files. Conf file = global, Rc file = user specific
#if [ "$version" != "$Sample_Conf" ] || [ "$version" != "$Sample_Rc" ]; then
if [ "$version" != "$Camp_Conf" ]; then
	Show_Err 12 ""
	exit 12
fi

##############################################################################
# CHECK ARGUMENTS
#
case "$cmd" in
#    '')
#	if [ "$#" -eq 1 ]; then				# parameter count ok
#		arg1="$1"
#		shift
#		#args="$@"
#		#shift $#
#	else						# error in param count
#		Show_Err 2 ""
#		exit 2
#	fi
#	;;
    *)
	if [ "$#" -ne 0 ]; then				# error in param count
		Show_Err 2 ""
		exit 2
	fi
	;;
esac

##############################################################################
# LOCK

##############################################################################
# MAINPROGRAM
##############################################################################
#
if [ "$debug" == "yes" ]; then				# DEBUG
#	echo "DEBUG Main: $# $@" >&2
	$debuglog Main: $# $@
fi

# Check what to do (sub commands, options and args are removed from cmdline)
case "$cmd" in
    '')
	mainproc
	err=$?
	clear
	;;
    -h)
	helptext
	exit 0
	;;
    -V)
	echo "${scriptname}: (${package}) $package_file ${version}-${release}"
	exit 0
	;;
    -f)
	fselect_dialog "SELECT FILE" "$startdir"
	err=$?
	clear
	;;
    *)							# error
	Show_Err 6 ""
	err=6
	;;
esac

#rm -f $lockfile

exit $err
