#    Jools -- a graphical puzzle game in the Tetris tradition
#    
#    Copyright (C) 2002-2003 Paul Pelzl
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

# playlist.py
#
# playlist handling code.
#


import pygame.mixer, os
from joolsutils import *
from config import *
from globals import *


OFF     = 0
TITLE   = 1
TIMED   = 2
UNTIMED = 3


UnrecognizedMusic = "unrecognized music module formats"


# alphabetical comparison (used in a sort() call)
def strCmp(a, b):
   if a < b:
      return -1
   elif a > b:
      return 1
   else:
      return 0


class Playlist:
   # initialize music playlists.
   def __init__(self, audio):
      self.audio = audio

      os.chdir(os.path.join(MEDIAROOT, "music"))

      titleRelList = os.listdir("title")
      timedRelList = os.listdir("timed")
      untimedRelList = os.listdir("untimed")
      # get rid of the empty files used to appease distutils
      removeDotfiles(titleRelList)
      removeDotfiles(timedRelList)
      removeDotfiles(untimedRelList)
      # sort alphabetically
      titleRelList.sort(strCmp)
      timedRelList.sort(strCmp)
      untimedRelList.sort(strCmp)
      # convert to absolute paths
      self.titleTracks   = absPathList("title",titleRelList)
      self.timedTracks   = absPathList("timed",timedRelList)
      self.untimedTracks = absPathList("untimed",untimedRelList)
      os.chdir("..")

      # override with music from $HOME, if available
      dummyDir = "~/.jools/music"
      homeMusicDir = os.path.expanduser(dummyDir)
      # catch for OS's that don't implement $HOME
      if homeMusicDir == dummyDir:
         homeMusicDir = ".jools/music"
      homeMusicDir = os.path.normpath(homeMusicDir)

      if os.path.exists(homeMusicDir):
         print "Checking for playlist in "+homeMusicDir+"..." 
         try:
            titleDir = os.path.join(homeMusicDir, "title")
            tempTracks = absPathList(titleDir, os.listdir(titleDir))
            if len(tempTracks) > 0:
               self.titleTracks = tempTracks
               self.titleTracks.sort(strCmp)
               print "(found title music)"
         except:
            pass
         try:
            timedDir = os.path.join(homeMusicDir, "timed")
            tempTracks = absPathList(timedDir, os.listdir(timedDir))
            if len(tempTracks) > 0:
               self.timedTracks = tempTracks
               self.timedTracks.sort(strCmp)
               print "(found timed mode music)"
         except:
            pass
         try:
            untimedDir = os.path.join(homeMusicDir, "untimed")
            tempTracks = absPathList(untimedDir, os.listdir(untimedDir))
            if len(tempTracks) > 0:
               self.untimedTracks = tempTracks
               self.untimedTracks.sort(strCmp)
               print "(found untimed mode music)"
         except:
            pass

      else:
         # if the music directory in $HOME does not exist, create it.
         dummyDir = "~/.jools"
         joolsDir = os.path.expanduser(dummyDir)
         # catch for OS's that don't implement $HOME
         if joolsDir == dummyDir:
            joolsDir = ".jools"
         joolsDir = os.path.normpath(joolsDir)

         if not os.path.exists(joolsDir):
            os.mkdir(joolsDir)
         os.mkdir(homeMusicDir)
         os.mkdir(os.path.join(homeMusicDir,"title"))
         os.mkdir(os.path.join(homeMusicDir,"timed"))
         os.mkdir(os.path.join(homeMusicDir,"untimed"))

      # return values are tuples indicating both the tracks to play
      # and the current track being played.
      self.currTitleTrack   = -1
      self.currTimedTrack   = -1
      self.currUntimedTrack = -1



   # auxiliary recursive function used in play_next()
   def loadNextAux(self, trackList, currTrack, originalTrack):
      if currTrack < len(trackList)-1:
         currTrack += 1
      else:
         currTrack = 0

      # if currTrack == originalTrack, then we scanned the
      # entire playlist without finding a suitable track.
      # Exit without playing anything.
      if currTrack != originalTrack:
         try:
            if self.audio.Capable:
               pygame.mixer.music.load(trackList[currTrack])
         except:
            print "Warning: unable to load track \""+trackList[currTrack]+"\"."
            currTrack = self.loadNextAux(trackList, currTrack, originalTrack)
      else:
         raise UnrecognizedMusic
      return currTrack



   # play the next track from the appropriate list
   def playNext(self, musicMode):
      if musicMode == TITLE:
         trackList = self.titleTracks
         currTrack = self.currTitleTrack
         volume = TITLE_BASE_VOL * self.audio.musicMultiplier
      elif musicMode == TIMED:
         trackList = self.timedTracks
         currTrack = self.currTimedTrack
         volume = TIMED_BASE_VOL * self.audio.musicMultiplier
      else:
         trackList = self.untimedTracks
         currTrack = self.currUntimedTrack
         volume = UNTIMED_BASE_VOL * self.audio.musicMultiplier

      if self.audio.Capable:
         pygame.mixer.music.set_volume(volume)


      trackLoaded = 0
      if self.audio.Capable:
         pygame.mixer.music.stop()
      if len(trackList) >= 1:
         if currTrack < len(trackList)-1:
            currTrack += 1
         else:
            currTrack = 0

         try:
            if self.audio.Capable:
               pygame.mixer.music.load(trackList[currTrack])
            trackLoaded = 1
         except:
            # if playing the next track fails, continue trying to
            # play the remaining tracks.
            print "Warning: unable to load track \""+trackList[currTrack]+"\"."
            try:
               currTrack = self.loadNextAux(trackList, currTrack, currTrack)
               trackLoaded = 1
            except UnrecognizedMusic:
               print "Warning: all music files have unrecognized formats."
               currTrack = -1

         if trackLoaded and self.audio.Capable and self.audio.musicEnabled:
            pygame.mixer.music.set_volume(volume)
            pygame.mixer.music.play(-1)
            # workaround: pygame 1.4 requires volume set *after* music plays
            pygame.mixer.music.set_volume(volume)

      if musicMode == TITLE:
         self.currTitleTrack = currTrack
      elif musicMode == TIMED:
         self.currTimedTrack = currTrack
      else:
         self.currUntimedTrack = currTrack


# arch-tag: playlist handler

