#!/usr/bin/perl
# written 2014 by Bernhard M. Wiedemann
# licensed under the terms of the GNU GPL v2 or later
# see the included COPYING file for details
use strict;
use warnings;
# zypper in perl-Alien-SDL perl-SDL

use SDL::Mixer;
use SDL::Mixer::Channels;
use SDL::Mixer::Samples;
use Time::HiRes qw(gettimeofday usleep);

SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 );

my %sound=();
my $datadir;
for($ENV{AUDIOCLOCKDATADIR}, "/usr/share/audioclock", ".") {
  next unless defined $_ and -e $_;
  $datadir = $_;
  last;
}
for(qw"tick-tack clack dong-end dong-end-deep") {
  $sound{$_} = SDL::Mixer::Samples::load_WAV($datadir."/$_.wav")
    or die "failed to load $_: $!";
}

sub play($)
{
  my $s = $sound{$_[0]};
  SDL::Mixer::Channels::play_channel(1, $s, 0)
    or die "failed to play $_[0] $s: $!";
}

sub waittosec()
{
  my $t=[gettimeofday()];
  usleep(($t->[0]&1)*1000000 + 1000000-$t->[1]);
  return $t;
}

sub dong(;$$)
{ my $t=shift||1.9;
  my $deep=shift||"";
  play('dong-end'.$deep); sleep $t;
  waittosec;
}
sub clack()
{
  play('clack');
  usleep 1900000;
}

sub dongs($;$$)
{ my $n=shift;
  my $fullhour=shift||0;
  my $deep=shift;
  for(2..$n) {dong(1.9, $deep)}
  dong($fullhour?5.9:13.9, $deep);
}

sub ticktack()
{
  my $t=waittosec;
  my ($s,$m,$h) = localtime($t->[0]);
  if($s>57) { # every minute
    clack();
    waittosec;
  }
  if(!($m % 15) and $s<3) { # dong every quarter hour
    my $quarter = int($m/15) || 4;
    my $fullhour = ($m == 0);
    dongs($quarter, $fullhour);
    if($fullhour) {
      # full hour count (considering local timezone)
      my $h = $h % 12 || 12;
      dongs($h, 0, "-deep")
    }
  }
  play('tick-tack');
  usleep 1900000;
}


$SIG{TERM} = $SIG{INT} = sub {exit 0};

# main:
while(1) {
  ticktack;
}

