#!/usr/bin/perl

# xmms-share 2.91 by Zirias
# ~~~~~~~~~~~~~~~~~~~~~~~~
# --> check out gIRCSnet http://mini-chat.ath.cx/~ircs/ <--
#
# LICENSE :
# ~~~~~~~~~
# GPL (whichever version is the actual one at the moment)
# http://www.fsf.org/licenses/gpl.html
#
#
# Commands :
# ~~~~~~~~~~
#
# /XMMS			Announce the song you are listening in channel
#
# /XMDL [ON|OFF]	Enable/disable downloads via DCC
# 
# /XMAUTO [ADD|DEL] #chan
#         [LIST]
#         [CLEAR]
#			Modifiy/show/clear the list of channels for
#			auto-announce
# 
# /XMPREV		Go to previous song
#
# /XMNEXT		Go to next song
#
# /XMPL	(num)		Start playing (with track <num>)
#
# /XMST			Stop playing
#
# /XMPS			Pause playing
#
# /XMSEARCH <pattern>	Search playlist for songs matching <pattern>
# 			(use * and ? as wildcards)
#
# /XMRH			Rehash (re-read) the XMMS playlist
# 
# 
# Short Commands :
# /XMMS /XD /XA /XP /XN /XS
#
# I recommend you add keybindings for the commands /XMPREV and /XMNEXT
# C-PgUp and C-PgDn work great for example. So you can minimize xmms and
# control the playlist out of xchat :)




# Config :
# ~~~~~~~~

# set this to 1 to enable downloads initially
$dl_allow = 0;

# list of channels where you want to auto-announce per default
# @auto_chans = qw/#foo #bar/;
@auto_chans = qw//;

# *******************************************************
# do NOT change below here unless you know what you do :)
# *******************************************************

use Xmms::Remote ();
use POSIX;

IRC::print("\cB\cC4xmms-share \cC7v2.91\cO by \cB\cC10Z\cC3irias\cO loading ...");

IRC::register ("xmms-share", "2.91", "", "");

IRC::add_command_handler("xmms", "xmms_handler");
IRC::add_command_handler("xmdl", "switch_dl");
IRC::add_command_handler("xd", "switch_dl");
IRC::add_command_handler("xmauto", "auto_announce_handler");
IRC::add_command_handler("xa", "auto_announce_handler");
IRC::add_command_handler("xmnext", "xmms_next");
IRC::add_command_handler("xn", "xmms_next");
IRC::add_command_handler("xmprev", "xmms_previous");
IRC::add_command_handler("xp", "xmms_previous");
IRC::add_command_handler("xmrh", "xmms_rehash");
IRC::add_command_handler("xmpl", "xmms_play");
IRC::add_command_handler("xmst", "xmms_stop");
IRC::add_command_handler("xmps", "xmms_pause");
IRC::add_command_handler("xmsearch", "xmms_search");
IRC::add_command_handler("xs", "xmms_search");
IRC::add_print_handler("CTCP Generic", "getfile");
IRC::add_timeout_handler(1000, "auto_announce");

@playlist = qw//;
$length = 0;
$xmms_remote = Xmms::Remote->new();
$pl_pos = $xmms_remote->get_playlist_pos;

sub getplaylist {
	$length = $xmms_remote->get_playlist_length;
	for (my $i;$i<$length;$i++) {
		my $title = $xmms_remote->get_playlist_title($i);
		$title =~ s/(_[^_]*_[^_]*_)|( - )/ <> /;
		@playlist = (@playlist,"\cB".($i+1).".\cB ".$title);
	}
}

sub xmms_play {
	my $num = shift;
	if (($num=~/^[0-9]+$/)&&($num>0)&&($num<=$length)) {
		$xmms_remote->stop;
		$xmms_remote->set_playlist_pos($num-1);
	}
	$xmms_remote->play;
	return 1;
}

sub xmms_search {
	my $pattern = shift;
	if ($pattern !~ /^$/) {
		$pattern =~ s/([\&;\`'\\\|"~.<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;
		$pattern =~ s/\*/.*/g;
		$pattern =~ s/\?/./g;
		my @result = grep /$pattern/i, @playlist;
		my $num = @result;
		IRC::print("\c_$num Results:\c_");
		foreach(@result) {
			IRC::print($_);
		}
	} else {
		IRC::print("\cBUSAGE: /XMSEARCH <regex>\cB");
	}
	return 1;
}

sub xmms_stop {
	$xmms_remote->stop;
	return 1;
}

sub xmms_pause {
	$xmms_remote->pause;
	return 1;
}

sub xmms_next {
	if ($xmms_remote->is_playing) {
		$xmms_remote->playlist_next;
	}
	return 1;
}

sub xmms_previous {
	if ($xmms_remote->is_playing) {
		$xmms_remote->playlist_prev;
	}
	return 1;
}

sub xmms_handler {
	if ($xmms_remote->is_playing) {
		my $title = $xmms_remote->get_playlist_title;
		my $time = $xmms_remote->get_playlist_time($pl_pos)*0.001;
		my $min = floor($time*0.016666667);
		my $sec = int($time-$min*60.0);
		$time = sprintf("\cB[\cB%d:%02d\cB]\cB",$min,$sec);
		$title =~ s/(_[^_]*_[^_]*_)|( - )/ <> /;
		my $nick = IRC::get_info(1);
		my $dl = "";
		if ($dl_allow) {
			$dl = " (\cBDownload:\cB /CTCP $nick GETSONG)";
		}
		IRC::command("/me is listening to ={\c_ $title \c_}= $time$dl");
	}
	return 1;
}

sub xmms_rehash {
	@playlist=qw//;
	getplaylist;
	IRC::print("\cB\cC4xmms-share\cO: Playlist re-read.");
	return 1;
}

sub switch_dl {
	$line = shift;
	if ($line =~ /^ON$/i) {
		$dl_allow = 1;
		IRC::print("\cB\cC4xmms-share\cO: Downloads are now \cB\cC3enabled\cO.");
	} elsif ($line =~ /^OFF$/i) {
		$dl_allow = 0;
		IRC::print("\cB\cC4xmms-share\cO: Downloads are now \cB\cC7disabled\cO.");
	} else {
		IRC::print("\cBUSAGE: /XMDL [ON|OFF]");
	}
	return 1;
}

sub getfile {
	my $args = $_[0];
	$args =~ /^ *([^ ]+) ([^ ]+) *$/;
	my $type = $1;
	my $sender = $2;
	if ($type =~ /GETSONG/i) {
		if ($xmms_remote->is_playing) {
			if ($dl_allow) {
				$file = $xmms_remote->get_playlist_file;
				IRC::command('/DCC SEND '.$sender.' "'.$file.'"');
			} else {
				IRC::send_raw("NOTICE $sender :sorry, I do not want to share my songs at the moment.\r\n");
			}
		} else {
			IRC::send_raw("NOTICE $sender :I am not listening to any music at the moment.\r\n");
		}
	}
	return 0;
}

sub auto_announce_handler {
	my $line = shift;
	if ($line =~ /^ADD (#[^ ]+)$/i) {
		my $chan = $1;
		if (grep(/^$chan$/i,@auto_chans)) {
			IRC::print("\cB\cC4xmms-share\cO: Auto-Annonce already enabled in $chan.");
		} else {
			push(@auto_chans,$chan);
			IRC::print("\cB\cC4xmms-share\cO: Auto-Annonce enabled in $chan.");
		}
	} elsif ($line =~ /^DEL (#[^ ]+)$/i) {
		my $chan = $1;
		if (!grep(/^$chan$/i,@auto_chans)) {
			IRC::print("\cB\cC4xmms-share\cO: Auto-Annonce not enabled in $chan.");
		} else {
			my @tmp = ();
			while ($tmp = shift(@auto_chans)) {
				if (!($tmp =~ /^$chan$/i)) {
					push(@tmp,$tmp);
				}
			}
			@auto_chans=@tmp;
			IRC::print("\cB\cC4xmms-share\cO: Auto-Announce disabled in $chan.");
		}
	} elsif ($line =~ /^CLEAR$/i) {
		@auto_chans = qw//;
		IRC::print("\cB\cC4xmms-share\cO: Auto-Announce channel list is empty.");
	} elsif ($line =~ /^LIST$/i) {
		if (@auto_chans) {
			IRC::print("\cB\cC4xmms-share\cO: Auto-Announce in channels \cB"
				. join(', ',@auto_chans) . "\cO.");
		} else {
			IRC::print("\cB\cC4xmms-share\cO: Auto-Announce channel list is empty.");
		}
	} else {
		IRC::print("\cBUSAGE: /XMAUTO [ ADD #chan | DEL #chan | LIST ].\cB");
	}
	return 1;
}

sub auto_announce {
	IRC::add_timeout_handler(1000, "auto_announce");
	my $newpos=$xmms_remote->get_playlist_pos;
	if ($newpos!=$pl_pos) {
		$pl_pos=$newpos;
		if ($xmms_remote->is_playing) {
			foreach (@auto_chans) {
				my $chan = $_;
				$title = $xmms_remote->get_playlist_title;
				my $time = $xmms_remote->get_playlist_time($pl_pos)*0.001;
				my $min = floor($time*0.016666667);
				my $sec = int($time-$min*60.0);
				$time = sprintf("\cB[\cB%d:%02d\cB]\cB",$min,$sec);
				$title =~ s/(_[^_]*_[^_]*_)|( - )/ <> /;
				my @clist = IRC::channel_list();
				if (join(" ",@clist) =~ /($chan) ([^ ]+) ([^ ]+)/i) {
					my $serv = $2;
					my $nick = $3;
					my $dl = "";
					if ($dl_allow) {
						$dl = " (\cBDownload:\cB /CTCP $nick GETSONG)";
					}
					IRC::command_with_server("/QUOTE PRIVMSG $chan :\cAACTION is listening to ={\c_ $title \c_}= $time$dl\cA\r\n",$serv);
					IRC::print_with_channel("\cC13* \cO$nick is listening to ={\c_ $title \c_}= $time$dl",$chan,$serv);
				}
			}
		}
	}
}

getplaylist;
1;
#end

