;;; irchat-pj-sound.el -- irchat-pj sound extension

;; Copyright (C) 1998,1999 TAKAHASHI Kaoru

;; Author: TAKAHASHI "beatmaria" Kaoru <kaoru@kaisei.org>
;; Created: 25 Dec 1998
;; Keywords: IRC, sound, irchat

;; CTCP-related modification: by simm@irc.fan.gr.jp, Sat, 18 Dec 1999 00:53:21 +0900

;; This file is part of irchat-pj

;;; Commentary:

;;; Code:
(provide 'irchat-pj-sound)

;; flags
(defvar irchat-pj-sound-words-list nil
  "*Beep list for irchat-pj.
Set a list of regular expression, and you get sound if match.")

(defvar irchat-pj-sound-when-bell t
  "*Output sound when bell(\\a) received.")

(defvar irchat-pj-sound-when-invited nil
  "*Output sound when invited.")

(defvar irchat-pj-sound-when-private nil
  "*Output sound when received private message.")

(defvar irchat-pj-sound-when-join nil
  "*Output sound when anyone join to your joined channel.")

(defvar irchat-pj-sound-when-part nil
  "*Output sound when anyone part from your joined channel.")

(defvar irchat-pj-sound-when-ctcp nil
  "*Output sound when anyone sends you or your joined channel CTCP message.")

(defvar irchat-pj-sound-when-error t
  "*Output sound when server sends you ERROR message.")

;; process
(defvar irchat-pj-sound-wav-player "play"
  "Executable program for playing WAV files.")

(defvar irchat-pj-sound-au-player "showaudio"
  "Executable program for playing sun AU format sound files.")

(defvar irchat-pj-sound-player-alist
  '(("\\.wav$" . irchat-pj-sound-wav-player)
    ("\\.au$"  . irchat-pj-sound-au-player))
  "Filetype and player variables alist.")

;; sound file directory
(defvar irchat-pj-sound-directory nil
  "*Default soundfile directory.
`expand-file-name' argument.")

;; sound file
(defvar irchat-pj-sound-words-file 'ding
  "*Default output sound file for keyword notify.
`ding' means beep.  `ignore' means mute.")

(defvar irchat-pj-sound-bell-file 'ding
  "*Output sound file when bell(\\a) recieved.
`ding' means beep.  `ignore' means mute.")

(defvar irchat-pj-sound-invited-file 'ding
  "*Output sound file when invited.
`ding' means beep.  `ignore' means mute.")

(defvar irchat-pj-sound-private-file 'ding
  "*Output sound file when receive private massage.
`ding' means beep.  `ignore' means mute.")

(defvar irchat-pj-sound-join-file 'ding
  "*Default play sound file when anyone join channel.
`ding' means beep.  `ignore' means mute.")

(defvar irchat-pj-sound-part-file 'ding
  "*Default play sound file when anyone part channel.
`ding' means beep.  `ignore' means mute.")

(defvar irchat-pj-sound-ctcp-file 'ding
  "*Default play sound file when anyone send CTCP messge.
`ding' means beep.  `ignore' means mute.")

(defvar irchat-pj-sound-error-file 'ding
  "*Default play sound file when got ERROR messge.
`ding' means beep.  `ignore' means mute.")


;; default function
(defvar irchat-pj-sound-words-function 'irchat-pj-sound-play-words
  "Call function when anyone called.")

(defvar irchat-pj-sound-bell-function 'irchat-pj-sound-play-bell
  "Call function when bell(\\a) received.")

(defvar irchat-pj-sound-invited-function 'irchat-pj-sound-play-invited
  "Call function when invited.")

(defvar irchat-pj-sound-private-function 'irchat-pj-sound-play-private
  "Call function when received private message.")

(defvar irchat-pj-sound-join-function 'irchat-pj-sound-play-join
  "Call function when anyone join to your joined channel.")

(defvar irchat-pj-sound-part-function 'irchat-pj-sound-play-part
  "Call function when anyone part from your joined channel.")

(defvar irchat-pj-sound-ctcp-function 'irchat-pj-sound-play-ctcp
  "Call function when anyone send you or your joined channel CTCP message.")

(defvar irchat-pj-sound-error-function 'irchat-pj-sound-play-error
  "Call function when server send you ERROR message.")


;; utils
(defun irchat-pj-sound-assoc-string-match (key alist)
  "Return non-nil if  KEY `string-match' to the car of an element of ALIST.
The value is actually the element of ALIST whose car matches KEY."
  (let ((case-fold-search t))           ; ignore case
    (save-match-data
      (catch 'tag
        (while (consp alist)
          (if (string-match (car (car alist)) key)
              (throw 'tag (car alist))
            (setq alist (cdr alist))))))))

(defun irchat-pj-sound-play (sound)
  "If SOUND is string, play SOUND file sound.
If SOUND is symbol, funcall SOUND."
  (cond
   ;; function
   ((symbolp sound)
    (if (fboundp sound)
        (funcall sound)))
   ;; filename
   ((stringp sound)
    (irchat-pj-sound-play-file
     (expand-file-name sound irchat-pj-sound-directory)))))

(defun irchat-pj-sound-play-file (file)
  "If readble FILE, play FILE."
  (interactive "fSound file: ")         ; for test
  (if (file-readable-p file)
      (let ((player (symbol-value
                     (cdr (irchat-pj-sound-assoc-string-match
                           file irchat-pj-sound-player-alist)))))
        (cond
         ;; e.g. '("cp" file "/dev/audio")
         ((consp player)      
          (apply 'call-process
                 (car player)
                 nil 0 t
                 (mapcar 'eval (cdr player))))
         ;; e.g. "xplay"
         ((stringp player)
          (call-process player nil 0 t file))))))

;; default functions
(defun irchat-pj-sound-play-words ()
  "Keyword notify."
  (irchat-pj-sound-play irchat-pj-sound-words-file))

(defun irchat-pj-sound-play-bell ()
  "Ring bell."
  (irchat-pj-sound-play irchat-pj-sound-bell-file))

(defun irchat-pj-sound-play-invited ()
  "Invite notify."
  (irchat-pj-sound-play irchat-pj-sound-invited-file))

(defun irchat-pj-sound-play-private ()
  "Priv notify."
  (irchat-pj-sound-play irchat-pj-sound-private-file))

(defun irchat-pj-sound-play-join ()
  "Join notify."
  (or (irchat-match-me nick) ; join myself
      (irchat-pj-sound-play irchat-pj-sound-join-file)))

(defun irchat-pj-sound-play-part ()
  "Join notify."
  (or (irchat-match-me nick) ; part myself
      (irchat-pj-sound-play irchat-pj-sound-part-file)))

(defun irchat-pj-sound-play-ctcp ()
  "CTCP notify."
  (irchat-pj-sound-play irchat-pj-sound-ctcp-file))

(defun irchat-pj-sound-play-error ()
  "ERROR notify."
  (irchat-pj-sound-play irchat-pj-sound-error-file))


;; another function (undocumented)
(defvar irchat-pj-sound-words-regexp-alist ()
  "Alist of keyword(regexp) and soundfile pair.")

(defvar irchat-pj-sound-words-channel-alist ()
  "Alist of channel and soundfile pair for keyword notify.")

(defvar irchat-pj-sound-join-nick-alist ()
  "Alist of nick(regexp) and soundfile pair for join notify.")

(defvar irchat-pj-sound-join-channel-alist ()
  "Alist of channel and soundfile pair for join notify.")

(defvar irchat-pj-sound-part-nick-alist ()
  "Alist of nick(regexp) and soundfile pair for part notify.")

(defvar irchat-pj-sound-part-channel-alist ()
  "Alist of channel and soundfile pair for part notify.")

(defun irchat-pj-sound-play-words-another ()
  "Keyword notify."
  (irchat-pj-sound-play
   (or (cdr (irchat-pj-sound-assoc-string-match
             ;; temp is matched msg.
             temp irchat-pj-sound-words-regexp-alist))
       (cdr (assoc chan irchat-pj-sound-words-channel-alist))
       irchat-pj-sound-words-file)))

(defun irchat-pj-sound-play-join-another ()
  "Join notify."
  (or (irchat-match-me nick) ; join myself
      (irchat-pj-sound-play
       (or (cdr (irchat-pj-sound-assoc-string-match
		 nick irchat-pj-sound-join-nick-alist))
	   (cdr (assoc chan irchat-pj-sound-join-channel-alist))
	   irchat-pj-sound-join-file))))

(defun irchat-pj-sound-play-join-another ()
  "Part notify."
  (or (irchat-match-me nick) ; part myself
      (irchat-pj-sound-play
       (or (cdr (irchat-pj-sound-assoc-string-match
		 nick irchat-pj-sound-part-nick-alist))
	   (cdr (assoc chan irchat-pj-sound-part-channel-alist))
	   irchat-pj-sound-part-file))))

;;; irchat-pj-sound.el ends here
