#!/bin/bash

# Velmi jednoduch shellov skript pro sprvu sbrky CD. 
# Copyright (C) 1996-2007 Wiley Publishing Inc.

# Tento program je voln iitelnm softwarem; mete jej 
# libovoln distribuovat a/nebo jakkoli upravovat za podmnek 
# GNU General Public License, vydan nadac 
# Free Software Foundation, a to ve verzi 2 tto Licence 
# nebo libovoln novj verzi.

# Program distribuujeme v nadji, e bude nkomu k nemu
# dobr, ale je BEZ ZRUKY a dokonce i bez pedpokldan
# zruky OBCHODOVATELNOSTI nebo VHODNOSTI
# K URITMU ELU. Podrobnj informace najdete 
# v GNU General Public License.

# Spolu s tmto programem byste mli obdret kopii GNU 
# General Public License; pokud jste ji nedostali, napite na adresu
# Free Software Foundation, Inc., 
# 675 Mass Ave, Cambridge, MA 02139, USA.

menu_choice=""
current_cd=""
title_file="title.cdb"
tracks_file="tracks.cdb"
temp_file=/tmp/cdb.$$
trap 'rm -f $temp_file' EXIT

# Dle nadefinujeme funkce - jak jsme si ekli, ty se mus nachzet ze zatku skriptu, 
# abychom je mohli z dalho kdu volat. Nejprve nadefinujeme dv jednoduch utility, 
# dky kterm nebudeme muset stejn kd zapisovat na mnoha mstech programu opakovan.

get_return() {
  echo -e "Stisknte Enter \c "
  read x
  return 0
}

get_confirm() {
  echo -e "Jste si jist? \c "
  while true
  do
    read x
    case "$x" in
			a | ano | A | Ano | ANO )
				return 0;;
			n | ne | N | Ne | NE )
				echo
				echo "Zrueno"
				return 1;;
			*) echo "Napite prosm ano nebo ne" ;;
		esac
	done
}

#	Dostvme se k hlavn funkci pro obsluhu nabdky, set_menu_choice. 
# Konkrtn obsah nabdky se dynamicky mn - pokud je vybrna poloka 
# uritho CD, dopln se do n dal volby.
# Nezapomete, e pkaz echo -e nemus bt do nkterch shell penositeln.

set_menu_choice() {
	clear
	echo "Volby :-"
	echo
	echo " a) Pidat nov CD"
	echo " f) Hledat CD"
	echo " c) Zjistit poet CD a stop v katalogu"
	if [ "$cdcatnum" != "" ]; then
		echo " l) Vypsat stopy na CD $cdtitle"
		echo " r) Smazat CD $cdtitle"
		echo " u) Aktualizovat informace o stopch na CD $cdtitle"
	fi
	echo " q) Konec"
	echo
	echo -e "Napite prosm psmeno volby a stisknte Enter \c "
	read menu_choice
	return
}

# Nsleduj jet dv velice krtk funkce, insert_title a insert_track, kter pidvaj 
# informace do databzovch soubor. I kdy nkte lid takovto jednodkov funkce 
# nemaj rdi, hodn nm pomhaj zlepit itelnost jinch funkc.
# Jako dal v poad definujeme vrazn rozshlej funkci add_record_track, 
# kter je vyuv. Zmnn funkce nejprve pomoc kontroly shody vzorku ov, 
# jestli zadan text neobsahuje rky (protoe ty pouvme jako oddlova pol), 
# a pot pomoc vhodnch aritmetickch operac zv aktuln slo stopy pi pidvn stop:

insert_title() {
  echo $* >> $title_file
  return
}

insert_track() {
  echo $* >> $tracks_file
  return
}

add_record_tracks() {
	echo "Zadejte informace o stopch na tomto CD"
	echo "Po zadn posledn stopy napite q"
	cdtrack=1
	cdttitle=""
	while [ "$cdttitle" != "q" ]
	do
		echo -e "Stopa disku $cdtrack, nzev stopy? \c "
		read tmp
		cdttitle=${tmp%%,*}
		if [ "$tmp" != "$cdttitle" ]; then
  		echo "Je mi lto, rky nejsou povoleny"
      continue
    fi
    if [ -n "$cdttitle" ] ; then
      if [ "$cdttitle" != "q" ]; then
        insert_track $cdcatnum,$cdtrack,$cdttitle
      fi
    else
      cdtrack=$((cdtrack-1))
    fi
  cdtrack=$((cdtrack+1))
  done
}

# Funkce add_records umouje zadvn hlavnch (titulovch) informac pro nov CD.

add_records() {
	# Vzva k zadn zkladnch informac 

	echo -e "Zadejte katalogov nzev \c "
	read tmp
	cdcatnum=${tmp%%,*}

	echo -e "Zadejte titul \c "
	read tmp
	cdtitle=${tmp%%,*}

	echo -e "Zadejte nr \c "
	read tmp
	cdtype=${tmp%%,*}

	echo -e "Zadejte skladatele nebo interpreta \c "
	read tmp
	cdac=${tmp%%,*}

	# Zjistme, jestli uivatel skuten chce zadat informace 

	echo Budu pidvat novou poloku 
	echo "$cdcatnum $cdtitle $cdtype $cdac"

	# Po potvrzen pidme zznam na konec souboru s tituly 

	if get_confirm ; then
		insert_title $cdcatnum,$cdtitle,$cdtype,$cdac
		add_record_tracks
	else
		remove_records
	fi

return
}

# Pechzme k definici funkce find_cd, kter pomoc pkazu grep vyhledv v katalogu
# (souboru s tituly) zadan nzev. Zde bychom potebovali vdt, kolikrt byl poadovan 
# etzec nalezen, ale grep vrac jen informaci, jestli byla shoda nalezena nulakrt nebo
# vcekrt. Vsledky hledn musme proto uloit do souboru, kde bude ke kad shod jeden
# dek, a pot zjistit poet dk tohoto souboru.
# Poet slov zjistme pkazem wc, kter ve svm vstupu mezerami oddluje poet dk, 
# slov a znak v souboru. Zpisem $(wc -l $temp_file) nateme z vsledk prvn parametr 
# a zapeme jej do promnn linesfound. Pokud bychom potebovali i dal parametr, 
# piadili bychom vstup z pkazu pomoc konstrukce set do pslun parametrick 
# promnn shellu. Do promnn IFS (Internal Field Separator) musme zapsat rku 
# jako poadovan oddlova. Alternativou je pkaz cut.

find_cd() {
	if [ "$1" = "n" ]; then
		asklist=n
	else
		asklist=y
	fi
	cdcatnum=""
	echo -e "Zadejte etzec, kter se m vyhledat mezi tituly CD \c "
	read searchstr
	if [ "$searchstr" = "" ]; then
		return 0
	fi

	grep "$searchstr" $title_file > $temp_file

	set $(wc -l $temp_file)
	linesfound=$l

	case "$linesfound" in
	0)  	echo "Je mi lto, nic jsem nenael"
				get_return
				return 0
		  	;;
	1)    ;;
	2)    echo "Je mi lto, nzev nen jednoznan."
				echo "Nalezeny zznamy:"
				cat $temp_file
				get_return
				return 0
	esac

	IFS=","
	read cdcatnum cdtitle cdtype cdac < $temp_file
	IFS=" "

	if [ -z "$cdcatnum" ]; then
		echo "Je mi lto, ze $temp_file nemohu nast pole katalogu"
		get_return
		return 0
	fi

	echo
	echo Katalogov slo: $cdcatnum
	echo Titul: $cdtitle
	echo nr: $cdtype
	echo Skladatel/interpret: $cdac
	echo
	get_return

	if [ "$asklist" = "y" ]; then
		echo -e "Zobrazit stopy tohoto CD? \c "
		read x
		if [ "$x" = "y" ]; then
			echo
			list_tracks
			echo
		fi
	fi
	return 1
}

# Funkce update_cd slou k aktualizaci, tedy novmu zadn informac o CD. Vimnte si,
# e zde pomoc utility grep vyhledme vechny dky, kter zanaj (proto ^) etzcem 
# $cdcatnum a za nm nsleduje rka ,; vraz $cdcatnum musme zapsat do sloench 
# zvorek {}, aby mezi jeho hodnotou a rkou nemusela bt pi hledn mezera. Do 
# sloench zvorek {} jsme ve funkci zapsali tak skupinu pkaz, kter se 
# provdj, pokud voln get_confirm vrt true

update_cd() {
	if [ -z "$cdcatnum" ]; then
		echo "Nejprve muste vybrat CD"
		find_cd n
	fi
	if [ -n "$cdcatnum" ]; then
		echo "Aktuln stopy jsou :-"
		list_tracks
		echo
		echo "Nyn znovu zadme stopy pro CD $cdtitle"
		get_confirm && {
			grep -v "^${cdcatnum}," $tracks_file > $temp_file
			mv $temp_file $tracks_file
			echo
			add_record_tracks
		}
	fi
	return
}

# Jednoduch funkce count_cds rychle zjist poet CD a stop v databzi

count_cds() {
  set $(wc -l $title_file)
  num_titles=$1
  set $(wc -l $tracks_file)
  num_tracks=$1
  echo nalezeno $num_titles CD, na nich celkem $num_tracks stop
  get_return
  return
}

# Funkce remove_records odstran zznamy z databzovch soubor, piem pkazem 
# grep -v vyhled (a pot odstran) vechny shodn etzce. Na tomto mst musme
# pout doasn soubor; kdybychom zkusili napsat
# grep -v "^$cdcatnum" > $title_file
# pak by se soubor $title_file dky pesmrovn > okamit smazal, 
# jet ped sputnm procesu grep - a ten by tm pdem etl z przdnho souboru

remove_records() {
  if [ -z "$cdcatnum" ]; then
		echo Nejprve muste vybrat CD
    find_cd n
  fi
  if [ -n "$cdcatnum" ]; then
		echo "Nyn odstrante CD $cdtitle"
    get_confirm && {
      grep -v "^${cdcatnum}," $title_file > $temp_file
      mv $temp_file $title_file
      grep -v "^${cdcatnum}," $tracks_file > $temp_file
      mv $temp_file $tracks_file
      cdcatnum=""
			echo Poloka odstranna
    }
    get_return
  fi
  return
}

#	Tak funkce list_tracks vol utilitu grep a hled s n poadovan dky; 
# pot pkazem cut ozne potebn pole a pkazem more zajist strnkovan 
# vstup. Pokud si te pedstavte, jak rozshl program by namsto tchto 
# 20 dk bylo nutn napsat v C, urit pochopte, jakm je shell skvlm 
# nstrojem pro programovn

list_tracks() {
  if [ "$cdcatnum" = "" ]; then
    echo nen vybrno dn CD
    return
  else
    grep "^${cdcatnum}," $tracks_file > $temp_file
    num_tracks=$(wc -l $temp_file)
    if [ "$num_tracks" = "0" ]; then
			echo pro CD $cdtitle nebyly nalezeny dn stopy
    else { 
      echo
      echo "$cdtitle :-"
      echo 
      cut -f 2- -d , $temp_file 
      echo 
    } | ${PAGER:-more}
    fi
  fi
  get_return
  return
}

# Tm jsme nadefinovali vechny funkce a konen se dostvme k hlavnmu programu.
# Prvnch nkolik dk uprav veker soubory do znmho stavu; pot vyvolme 
# funkci set_menu_choice a zadme se podle jejch vsledk.
# Po vbru volby quit smaeme doasn soubor, vypeme zprvu a skonme skript ve stavu spnho ukonen

rm -f $temp_file
if [ ! -f $title_file ]; then
  touch $title_file
fi
if [ ! -f $tracks_file ]; then
  touch $tracks_file
fi

# Nyn nsleduje vlastn kd aplikace

clear
echo
echo
echo "Mini CD manager"
sleep 1

quit=n
while [ "$quit" != "y" ];
do
  set_menu_choice
  echo $menu_choice;
  case "$menu_choice" in
    a) add_records;;
    r) remove_records;;
    f) find_cd y;;
    u) update_cd;;
    c) count_cds;;
    l) list_tracks;;
    b) 
      echo
      more $title_file
      echo
      get_return;;
    q | Q ) quit=y;;
    *) echo "Je mi lto, volba nen platn";;
  esac
done

# Uklidit a skonit 

rm -f $temp_file
echo "Konec"

exit 0
