#!/usr/bin/perl

##################################################
#
# GiantDisc mp3 Jukebox
# 
# © 2000-2003, Rolf Brugger
#
##################################################


# Giant Disc Command dispatcher
#
# Listens on the specified interface for GiantDisc commands
# and executes them.
#
# A command consists of one or more text lines. Usually, a text
# line is an array of tabulator separated fields, where the first
# field specifies the command, and the following fields are the
# parameters. If a command consists of more than one line, the 
# end of a command is then given back an empty line (= two con-
# secutive newline characters).
#


### Packages
use DBI;
use strict;
use lib '/home/music/bin';
use gdio;
use gdserv;
use gdparams;
use gdupdate;

use Sys::Hostname;

### Set parameter defaults
$gdparms::dbhost   = `hostname -i`;	# IP address of database server
chop($gdparms::dbhost);
my $commmode = $gdio::rs232_mode;       # rs232, tcpip, ...
my $serialdevice = "/dev/ttyS0";
my $serialspeed = 19200;
my $tcpiphost = `hostname -i`; chop($tcpiphost);
my $tcpipport = 26468;
my $playerhost = hostname();	# default: local player
my $playertype = 0; # audio0  also  'playmode'  implicitly on channel 0
my $playerdevice = "2020";
my $logtargetstr = "stdout";
my $logtarget;


###
my $cfgfilename = gdparams::get_configfilename();
### read configuration file 
gdparams::get_configfile_params($cfgfilename,
        \$gdparms::dbhost, 
        \$commmode,
        \$serialdevice, \$serialspeed,
        \$tcpiphost, \$tcpipport,
	    \$playerhost, \$playertype, \$playerdevice,
        \$logtargetstr);

### get commandline parameters
gdparams::get_commandline_params(\$gdparms::dbhost, 
        \$commmode,
        \$serialdevice, \$serialspeed,
        \$tcpiphost, \$tcpipport,
	    \$playerhost, \$playertype, \$playerdevice, 
	    \$logtargetstr); # ARGV passed implicitly


# translate logtarget string to integer
$logtarget = gdparams::logtarget_to_int($logtargetstr);


### Initialization
my $uichannel;   # how does the palm communicate with the server?
                 # (Needed to distinguish between server instances
                 #  on one machine. Every server instance gets its
                 #  own $playerid.)

# Init Communication
if    ($commmode == 1){ # rs232_mode
  gdio::serio_init($logtarget, $serialdevice, $serialspeed);
  $uichannel = $serialdevice.":".$serialspeed;
}
elsif ($commmode == 2){ # tcpip server mode
  gdio::tcpip_srv_init($logtarget, $tcpiphost, $tcpipport);
  $uichannel = $tcpiphost.":".$tcpipport;
}
elsif ($commmode == 3){ # tcpip client mode
  gdio::tcpip_cli_init($logtarget, $tcpiphost, 3001);
  $uichannel = $tcpiphost.":".$tcpipport;
}
else{
  print "Error: unknown communication mode '$commmode'\n";
}

### Init
gdserv::init_server($gdparms::dbhost, $logtarget);
### init player (server instance, palm command dispatcher)
my $playerid = 
gdserv::init_player($playerhost, $uichannel, $cfgfilename); # also reads remaining params form .gdconfig

print "### ID of this instance of gdd (playerid): $playerid\n";

### write overridden parameters into parameter database
#param_set_value

### init playernb 0 (main sound out device) 
gdserv::init_playerstate($playerhost, $playertype, $playerdevice);

# Calculate genre and language frequencies
gdserv::recalc_table_frequencies();


### Variables & constants
my ($cmd, $cmdstring, @params);
my ($tstamp, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
my $logday = -1;

### Some initial Checks
#gdupdate::check_new_mp3info080();

### Prepare verbose or log output
my $base = gdparams::gdbase();
#unlink <$base/tmp/gdlog*.txt>;
check_logfile($logday, (gmtime)[6], $base, $playerid, $logtarget);

if($logtarget == 0){#devnull
  open OUTLOG, ">/dev/null";
  select OUTLOG;
}

### Begin main
print ("Giant Disc Server started\n");


while (1){ # infinite loop

while ( gdio::check_connection() ) 
        # While we still have a connection, loop around on this socket
        # otherwise the Palm has disconnected and we need to wait for
        # another connection
{
  $cmdstring="";
  $cmdstring=gdio::getline();
  chop($cmdstring);
  print("Command received: $cmdstring");
  @params = split('\t', $cmdstring);
  $cmd = shift(@params);
  $cmd =~ m/\W*(\w+)/;	# filter nonword characters (Palm sends trash when ser-port is opened)
  $cmd = $1;


  ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=gmtime;
  $tstamp = sprintf "%d/%02d/%02d-%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min;

  check_logfile($logday, (gmtime)[6], $base, $playerid, $logtarget);

  ### Track routines
  if(   $cmd eq "qrytr"){
    print ("\n$tstamp Query Tracks and List: @params \n");
    gdserv::query_tracks_list(@params);
  }
  elsif(   $cmd eq "qryst"){
    print ("\n$tstamp Query Streams and List: @params \n");
    gdserv::query_streams_list(@params);
  }
  elsif($cmd eq "gentrqry"){
    print ("\n$tstamp Generic Track Query: @params \n");
    gdserv::generic_track_query(@params);
  }
  elsif($cmd eq "qrandtr"){
    print ("\n$tstamp Random Query Track (prepare): @params \n");
    gdserv::query_random_tracks(1, @params);
  }
  elsif($cmd eq "qrandst"){
    print ("\n$tstamp Random Query Streams (prepare): @params \n");
    gdserv::query_random_tracks(2, @params);
  }
#  elsif($cmd eq "q1tr"){
#    print ("\n$tstamp Query one Track: @params \n");
#    gdserv::query_single_track(@params);
#  }
  elsif($cmd eq "qryar"){
    print ("\n$tstamp Query Artists: @params \n");
    gdserv::query_artists_list(@params);
  }
  elsif($cmd eq "genarqry"){
    print ("\n$tstamp Generic Artists Query: @params \n");
    gdserv::generic_artists_query(@params);
  }
  elsif($cmd eq "qrandar"){
    print ("\n$tstamp Random Query Artist (prepare): @params \n");
    gdserv::query_random_artists(@params);
  }
  elsif($cmd eq "gtdet"){
    print ("\n$tstamp Get Track Details for @params\n");
    gdserv::get_track_details(@params);
  }
  elsif($cmd eq "trdelete"){
    print ("\n$tstamp delete track\n");
    gdserv::delete_track(@params);
  }
  elsif($cmd eq "gtlyr"){
    print ("\n$tstamp Get Track Lyrics for @params\n");
    gdserv::get_track_lyrics(@params);
  }
  elsif($cmd eq "uptlyr"){
    print ("\n$tstamp Update Track Lyrics\n");
    gdserv::update_track_lyrics(@params);
  }
  elsif($cmd eq "trimmp3file"){
    print ("\n$tstamp Trim mp3 file @params\n");
    gdserv::trim_mp3_file(@params);
  }
  elsif($cmd eq "trimmp3fileundo"){
    print ("\n$tstamp Undo trim mp3 file @params\n");
    gdserv::trim_mp3_file_undo(@params);
  }


  ### Album routines
  elsif($cmd eq "qryal"){
    print ("\n$tstamp Query Albums: @params \n");
    gdserv::query_albums(@params); 
  }
  elsif($cmd eq "genalqry"){
    print ("\n$tstamp Generic Album Query: @params \n");
    gdserv::generic_album_query(@params);
  }
#  elsif($cmd eq "q1alt"){
#    print ("\n$tstamp Query one Album with Tracks and List: @params \n");
#    gdserv::query_single_album(@params);
#  }
  elsif($cmd eq "qrandal" or $cmd eq "qralt"){
    print ("\n$tstamp Random Query Albums (prepare): @params \n");
    gdserv::query_random_albums(@params);
  }
  elsif($cmd eq "galbdet"){
    print ("\n$tstamp Get Album Details for @params\n");
    gdserv::get_album_details(@params);
  }
  elsif($cmd eq "scancover"){
    print ("\n$tstamp Scan Album Cover page @params\n");
    gdserv::scan_album_cover(@params);
  }
  elsif($cmd eq "listcovers"){
    print ("\n$tstamp List Album Cover Images @params\n");
    gdserv::list_album_cover_images(@params);
  }
  elsif($cmd eq "altrdelete"){
    print ("\n$tstamp delete album and its tracks\n");
    gdserv::delete_album_tracks(@params);
  }

  elsif($cmd eq "getrandres"){
    print ("\n$tstamp get random results\n");
    gdserv::get_random_result(@params);
  }


  elsif($cmd eq "lago"){
    print ("\n$tstamp List all Genres ordered\n");
    gdserv::list_all_genres_ordered();
  }
  elsif($cmd eq "lalo"){
    print ("\n$tstamp List all Languages ordered\n");
    gdserv::list_all_languages_ordered();
  }
  elsif($cmd eq "glh"){
    print ("\n$tstamp get language hash\n");
    gdserv::get_language_hash();
  }
  elsif($cmd eq "ggh"){
    print ("\n$tstamp get genre hash\n");
    gdserv::get_genre_hash();
  }
  elsif($cmd eq "gth"){
    print ("\n$tstamp get types hash\n");
    gdserv::get_types_hash();
  }
  elsif($cmd eq "lmt"){
    print ("\n$tstamp list music types\n");
    gdserv::list_music_types();
  }
  elsif($cmd eq "lms"){
    print ("\n$tstamp list music sources\n");
    gdserv::list_music_sources();
  }
  elsif($cmd eq "gsh"){
    print ("\n$tstamp get sources hash\n");
    gdserv::get_sources_hash();
  }
  elsif($cmd eq "gahs"){
    print ("\n$tstamp get all hashes\n");
    gdserv::get_all_hashes();
  }
  elsif($cmd eq "recalcfreq"){
    print ("\n$tstamp recalculate genre/language frequencies\n");
    gdserv::recalc_table_frequencies();
  }
  

  ### Play commands
  elsif($cmd eq "cpt"){
    print ("\n$tstamp Play a track\n");
    gdserv::cmd_play_track(@params);
  }
  elsif($cmd eq "cpcdt"){
    print ("\n$tstamp Play a cd track\n");
    gdserv::cmd_play_cd_track(@params);
  }
  elsif($cmd eq "cpdirect"){
    print ("\n$tstamp Directly play mp3 track\n");
    gdserv::cmd_direct_play_mp3_track(@params);
  }
  elsif($cmd eq "csp"){
    print ("\n$tstamp Stop playing\n");
    gdserv::cmd_stop_playing(@params);
  }
  elsif($cmd eq "cspcd"){
    print ("\n$tstamp Stop playing CD\n");
    gdserv::cmd_stop_playing_cd(@params);
  }
  elsif($cmd eq "lcdd"){
    print ("\n$tstamp List cd directory\n");
    gdserv::list_cd_directory(@params);
  }
  elsif($cmd eq "lcddi"){
    print ("\n$tstamp List cd directory and gddb information @params\n");
    gdserv::list_cd_directory_info(@params);
  }
  elsif($cmd eq "libalbdi"){
    print ("\n$tstamp List inbox album directory @params\n");
    gdserv::list_inbox_album_directory(@params);
  }
  elsif($cmd eq "libdi"){
    print ("\n$tstamp List inbox directory and informations @params\n");
    gdserv::list_inbox_directory_info(@params);
  }  
  elsif($cmd eq "chcd"){
    print ("\n$tstamp Check current CD and compare with DB\n");
    gdserv::check_current_cd(@params);
  }
  elsif($cmd eq "ibxalbums"){
    print ("\n$tstamp list inbox album directories\n");
    gdserv::list_inbox_album_directories(@params);
  }
  elsif($cmd eq "impcover"){
    print ("\n$tstamp import inbox album cover images\n");
    gdserv::import_cover_img(@params);
  }
  elsif($cmd eq "opcdtray"){
    print ("\n$tstamp Open CD tray\n");
    gdserv::open_cd_tray(@params);
  }
  elsif($cmd eq "clcdtray"){
    print ("\n$tstamp Close CD tray\n");
    gdserv::close_cd_tray(@params);
  }


  elsif($cmd eq "repar"){
    print ("\n$tstamp Replace/insert album record \n");
    gdserv::replace_album_record(@params);
  }
  elsif($cmd eq "reccdt"){
    print ("\n$tstamp Record CD Track \n");
    gdserv::record_cd_track(@params);
  }
  elsif($cmd eq "recmpt"){
    print ("\n$tstamp Record mp3 Track \n");
    gdserv::import_audio_track(@params);
  }
  elsif($cmd eq "updtr"){
    print ("\n$tstamp Update Track Record\n");
    gdserv::update_track_record(@params);
  }
  elsif($cmd eq "grpst"){
    print ("\n$tstamp Get rip state \n");
    gdserv::get_rip_state();
  }
  elsif($cmd eq "gcpst"){
    print ("\n$tstamp Get compress state \n");
    gdserv::get_compress_state();
  }
  
  ### Playlist commands
  elsif($cmd eq "qrypl"){  
    print ("\n$tstamp Query saved Playlists and List: @params \n");
    gdserv::query_saved_playlists_list(@params);
  }
  elsif($cmd eq "qrandpl"){
    print ("\n$tstamp Random Query Playlists (prepare): @params \n");
    gdserv::query_random_playlists(@params);
  }
  elsif($cmd eq "spltracks"){  
    print ("\n$tstamp List Tracks of a saved Playlist: @params \n");
    gdserv::tracks_of_saved_playlist(@params);
  }
  elsif($cmd eq "plapp"){
    print ("\n$tstamp Playlist append tracks @params\n");
    gdserv::pl_append_tracks(@params);
  }
  elsif($cmd eq "plnew"){
    print ("\n$tstamp Playlist: new list \n");
    gdserv::pl_new_list(@params);
  }
  elsif($cmd eq "plsave"){
    print ("\n$tstamp Save current playlist\n");
    gdserv::pl_save_playlist(@params);
  }
  elsif($cmd eq "plexpempty"){
    print ("\n$tstamp Empty outbox\n");
    gdserv::pl_export_empty(@params);
  }
  elsif($cmd eq "plexplinks"){
    print ("\n$tstamp Export links to mp3-files to outbox\n");
    gdserv::pl_export_audiolinks(@params);
  }
  elsif($cmd eq "plupldplayeri"){
    print ("\n$tstamp Upload playlist to player info\n");
    gdserv::pl_upload_to_player_info(@params);
  }
  elsif($cmd eq "plupldplayer"){
    print ("\n$tstamp Upload playlist to player\n");
    gdserv::pl_upload_to_player(@params);
  }
  elsif($cmd eq "pldelete"){
    print ("\n$tstamp delete playlist\n");
    gdserv::pl_delete_playlist(@params);
  }
  elsif($cmd eq "plburn"){
    print ("\n$tstamp Burn audio CD\n");
    gdserv::pl_burn_cd(@params);
  }
  elsif($cmd eq "plremone"){
    print ("\n$tstamp Playlist: remove one track \n");
    gdserv::pl_remove_one(@params);
  }
  elsif($cmd eq "plreorder"){
    print ("\n$tstamp Playlist: reorder one track \n");
    gdserv::pl_reorder_one(@params);
  }
  elsif($cmd eq "plempt"){
    print ("\n$tstamp Empty playlist \n");
    gdserv::pl_empty();
  }
  elsif($cmd eq "plplay"){
    print ("\n$tstamp Playlist start playing \n");
    gdserv::pl_play();
  }
  elsif($cmd eq "plplayat"){
    print ("\n$tstamp Playlist start playing at pos @params\n");
    gdserv::pl_play_at(@params);
  }
  elsif($cmd eq "plchkshufpl"){
    print ("\n$tstamp Playlist check shuffle play \n");
    gdserv::pl_check_shuffleplay(@params);
  }
  elsif($cmd eq "pldoshufpl"){
    print ("\n$tstamp Playlist start shuffle play \n");
    gdserv::pl_start_shuffleplay(@params);
  }
  elsif($cmd eq "plstop"){
    print ("\n$tstamp Playlist stop playing \n");
    gdserv::pl_stop();
  }
  elsif($cmd eq "plpause"){
    print ("\n$tstamp Playlist pause \n");
    gdserv::pl_pause();
  }
  elsif($cmd eq "plrw"){
    print ("\n$tstamp Playlist rewind \n");
    gdserv::pl_rw();
  }
  elsif($cmd eq "plff"){
    print ("\n$tstamp Playlist fast forward \n");
    gdserv::pl_ff();
  }
  elsif($cmd eq "plgoto"){
    print ("\n$tstamp Playlist goto track @params\n");
    gdserv::pl_goto(@params);
  }
  elsif($cmd eq "plprev"){
    print ("\n$tstamp Playlist previous track \n");
    gdserv::pl_prev();
  }
  elsif($cmd eq "plnext"){
    print ("\n$tstamp Playlist next track \n");
    gdserv::pl_next();
  }
  elsif($cmd eq "plreload"){
    print ("\n$tstamp Reload playlist \n");
    gdserv::pl_reload_playlist();
  }
  elsif($cmd eq "plgetst"){
    print ("\n$tstamp Playlist: get playstate \n");
    gdserv::pl_get_curr_playstate();
  }

  ### Genre routines
  elsif($cmd eq "gendel"){
    print ("\n$tstamp Delete genre @params\n");
    gdserv::gen_delete(@params);
  }
  elsif($cmd eq "genmov"){
    print ("\n$tstamp Move genre @params\n");
    gdserv::gen_move(@params);
  }
  elsif($cmd eq "genren"){
    print ("\n$tstamp Rename genre @params\n");
    gdserv::gen_rename(@params);
  }
  elsif($cmd eq "genadd"){
    print ("\n$tstamp Add genre to @params\n");
    gdserv::gen_add(@params);
  }

  ### Music Types routines
  elsif($cmd eq "typdel"){
    print ("\n$tstamp delete music type @params\n");
    gdserv::typ_delete(@params);
  }
  elsif($cmd eq "typadd"){
    print ("\n$tstamp Add new music type @params\n");
    gdserv::typ_add(@params);
  }

  ### Volume routines
  elsif($cmd eq "volget"){
    print ("\n$tstamp Get volume \n");
    gdserv::get_volume();
  }
  elsif($cmd eq "volset"){
    print ("\n$tstamp Set volume \n");
    gdserv::set_volume(@params);
  }
  elsif($cmd eq "volinc"){
    print ("\n$tstamp Increase volume \n");
    gdserv::inc_volume(@params);
  }
  elsif($cmd eq "voldec"){
    print ("\n$tstamp Decrease volume \n");
    gdserv::dec_volume(@params);
  }
  elsif($cmd eq "volsave"){
    print ("\n$tstamp Save volume \n");
    gdserv::save_volume(@params);
  }

  ### Misc routines
  elsif($cmd eq "updbrdir"){
    print ("\n$tstamp Update browse directory \n");
    gdserv::update_browse_directory();
  }
  elsif($cmd eq "exportid3"){
    print ("\n$tstamp Export id3 tags \n");
    gdserv::export_id3_tags();
  }
  elsif($cmd eq "shutdown"){
    print ("\n$tstamp Shut down server! \n");
    gdserv::shut_down_server();
  }
  elsif($cmd eq "statistics"){
    print ("\n$tstamp Full Statistics \n");
    gdserv::full_statistics();
  }


  ### General Query and Shell Command 
  #   See also generic_ commands
  elsif($cmd eq "genquery"){
    print ("\n$tstamp General database query \n");
    gdserv::general_db_query(@params);
  }
  elsif($cmd eq "genquerycount"){
    print ("\n$tstamp General database query (count) \n");
    gdserv::general_db_query_count(@params);
  }
  elsif($cmd eq "gencommand"){
    print ("\n$tstamp General shell command \n");
    gdserv::general_sh_command(@params);
  }
  elsif($cmd eq "gencommandres"){
    print ("\n$tstamp General shell command (get result) \n");
    gdserv::general_sh_command_res(@params);
  }
  elsif($cmd eq "gencommandrescont"){
    print ("\n$tstamp General shell command (get continuously results) \n");
    gdserv::general_sh_command_res_continuous(@params);
  }
  elsif($cmd eq "gdbasedir"){
    print ("\n$tstamp Get GiantDisc base directory \n");
    gdserv::gd_basedir();
  }




  elsif($cmd eq "sertst"){
    print ("\n$tstamp Serial test routine \n");
    gdserv::serial_test();
  }
  elsif($cmd eq "ping"){
    print ("\n$tstamp Ping \n");
    gdserv::server_alive_test();
  }

  elsif($cmd eq "NULL"){		# When clients disconnects, we read "NULL"
    print ("\n$tstamp NULL Command\n"); # from the socket
  }
  else{
    print("\nERROR: Command $cmd unknown\n");
  }

}
}


###############################################################################


sub check_logfile{
# this routine checks if the server script has passed midnight since the 
# last activity. If this is the case, the current logfile is closed, and 
# a new one for the current day of week is opened
  my ($logday, $dayofweek, $base, $playerid, $logtarget) = @_;

  if($logtarget==1 && $logday!=$dayofweek){ #logfile
    if($logday>=0){
      close OUTLOG;
    }
    $logday = $dayofweek;
    open OUTLOG, ">$base/tmp/gdlog-$playerid-$logday.txt";
    OUTLOG->autoflush(1);
    select OUTLOG;
    $_[0] = $logday;
  }

}


#
