#!/usr/bin/perl -w
use strict;
use IPC::Open2;

#
# bits borrowed from l8nite's xmmsinfo script
#

our $PROGRAM = "iTunes Info for XChat (xchataqua)";
our $VERSION = "2.0.0";

BEGIN:
{
	IRC::register($PROGRAM, $VERSION, undef, undef);
	IRC::add_command_handler('itunes', 'show_itunes_info');
	IRC::add_command_handler('radio', 'show_radio_info');
	IRC::print("$PROGRAM $VERSION loaded.");
}

sub show_radio_info
{
	my $info = get_radio_info();
	unless (defined $info) {
		IRC::print("nothing returned.");
		return 1;
	}

	### Edit here to change output
	my $output = "/me is listening to ";
	if (value_ok($info->{stream}) or value_ok($info->{name})) {
		if (value_ok($info->{stream})) {
			$output .= '"' . $info->{stream} . '"';
		} elsif (value_ok($info->{name})) {
			$output .= '"' . $info->{name} . '"';
		}
		if (value_ok($info->{url})) {
			$output .= " at " . $info->{url};
		}
		IRC::command($output);
	} else {
		IRC::print("no stream info, ignoring.");
	}

	return 1;
}
sub show_itunes_info
{
	my $info = get_itunes_info();
	unless (defined $info) {
		IRC::print("nothing returned.");
		return 1;
	}

	### Edit here to change output
	### See get_itunes_info for the available keys.
	if (value_ok($info->{title})) {
		my $output = "/me is listening to ";
		$output .= '"' . $info->{title} . '"';
		if (value_ok($info->{artist})) {
			$output .= " by " . $info->{artist};
		}
		IRC::command($output);
	} else {
		IRC::print("no title, ignoring.");
	}

	return 1;
}

sub value_ok
{
	my $thing = shift;
	return undef unless defined $thing;
	return undef unless length $thing;
	return undef if $thing eq 'missing value';
	return 1;
}

# returns hash-ref.
# keys are: title, artist, bitrate, frequency, filetype, usectime, status,
#           usecposition
sub get_itunes_info
{
	my %info;
	my $script = qq(set AppleScript's text item delimiters to "::x::"\n);
	$script .= qq(set info to {name,artist,bit rate,sample rate,) .
	           qq(kind,duration} of current track\n);
	$script .= qq(copy {player state, player position} of application ) .
	           qq("iTunes" to the end of info\n);
	$script .= qq(return info as string);

	my $result = osascript($script);
	return undef unless (defined $result && length $result && $result =~ /\S/);

	my @fields = qw(title artist bitrate frequency
		filetype usectime status usecposition);
	for (split /::x::/, $result) {
		s/\n//g;
		s/^\s+//;
		s/\s+$//;
		$info{shift(@fields)} = $_;
	}
	$info{'time'} = sprintf('%02d:%02d:%02d', (gmtime $info{'usectime'})[2,1,0]);
	$info{'position'} = sprintf('%02d:%02d:%02d', (gmtime $info{'usecposition'})[2,1,0]);

	# clean up some crap names like D I G I T A L L Y
	$info{'title'} =~ s/([A-Z]) (?=[A-Z]) (?=[A-Z])/$1/g;

	# change frequency into khz
	$info{'frequency'} =~ s/([0-9]{3})$/.$1/;

	return \%info;
}

sub get_radio_info
{
	my %info;
	my $script = qq(set AppleScript's text item delimiters to "::x::"\n);
	$script .= qq(set info to {}\n) .
	           qq(copy current stream title to end of info\n);
	$script .= qq(copy {name, address} of current track to end of info\n);
	$script .= qq(return info as string);

	my $result = osascript($script);
	return undef unless (defined $result && length $result && $result =~ /\S/);

	my @fields = qw(stream name url);
	for (split /::x::/, $result) {
		s/\n//g;
		s/^\s+//;
		s/\s+$//;
		$info{shift(@fields)} = $_;
	}

	return \%info;
}

sub osascript
{
	my $script = shift;
	my ($read, $write);
	my $pid = IPC::Open2::open2($read, $write, 'osascript');
	print $write qq(tell application "iTunes"\n), $script, qq(\nend tell\n);
	close $write;
	my $data = do { local $/; <$read> };
	close $read;
	waitpid $pid, 0;
	return $data;
}

