#!/usr/bin/env python
"""
Example script to view and control itunes playback status
"""

import time

from soundforest.cli import Script, ScriptCommand, ScriptError

from pytunes import iTunesError
from pytunes.client import iTunes

INFO_FORMAT = """
Artist  %(artist)s
Album   %(album)s
Title   %(title)s
Genre   %(genre)s
Track   %(track_number)s/%(track_count)s
Length  %(time)s
Year    %(year)s
BPM     %(bpm)s
Comment %(comment)s
"""

class iTunesCLICommand(ScriptCommand):
    """iTunes CLI commands

    """
    def __init__(self, *args, **kwargs):
        super(iTunesCLICommand, self).__init__(*args, **kwargs)

        try:
            self.itunes = iTunes()
        except iTunesError as e:
            self.exit(1, 'Error connecting to iTunes: {0}'.format(e))


class InfoCommand(iTunesCLICommand):
    def run(self, args):
        if self.itunes.current_track:
            track = self.itunes.current_track
            if args.verbose:
                script.message(track.path)
            script.message(INFO_FORMAT % (track))
        else:
            script.message('No song playing')


class PlayCommand(iTunesCLICommand):
    def run(self, args):
        if args.track:
            self.itunes.play(args.track)

        if self.itunes.status == 'playing':
            self.itunes.pause()
        else:
            self.itunes.play()


class StopCommand(iTunesCLICommand):
    def run(self, args):
        if self.itunes.status in ('playing', 'paused',):
            self.itunes.stop()


class PreviousTrackCommand(iTunesCLICommand):
    def run(self, args):
        self.itunes.previous()


class NextTrackCommand(iTunesCLICommand):
    def run(self, args):
        self.itunes.next()


class ShuffleModeCommand(iTunesCLICommand):
    def run(self, args):
        if args.mode == 'enable':
            self.itunes.shuffle = True
        elif args.mode == 'disable':
            self.itunes.shuffle = False
        else:
            script.message('Shuffle {0}'.format(self.itunes.shuffle and 'enabled' or 'disabled'))


class VolumeCommand(iTunesCLICommand):
    def run(self, args):
        if args.volume is None:
            script.message('volume {0:d}%'.format(self.itunes.volume))
            return

        fade = True
        try:
            if args.volume.startswith('+'):
                volume = self.itunes.volume + int(args.volume[1:])
                if volume > 100:
                    volume = 100
            elif args.volume.startswith('-'):
                volume = self.itunes.volume - int(args.volume[1:])
                if volume < 0:
                    volume = 0
            else:
                volume = int(args.volume)
                fade = False
        except ValueError:
            script.exit(1, 'Invalid volume value {0}'.format(args.volume))

        try:
            if fade:
                if self.itunes.volume < volume:
                    while self.itunes.volume < volume:
                        self.itunes.volume = self.itunes.volume + 1
                        time.sleep(0.01)
                if self.itunes.volume > volume:
                    while self.itunes.volume > volume:
                        self.itunes.volume = self.itunes.volume - 1
                        time.sleep(0.01)
            else:
                self.itunes.volume = volume
        except iTunesError as e:
            script.exit(1,e)


class UpdateIndexCommand(iTunesCLICommand):
    def run(self, args):
        try:
            script.message('Update: {0}'.format(self.itunes.indexdb))
            self.itunes.indexdb.update()
        except iTunesError as e:
            script.error('Error updating {0}: {1}'.format(self.itunes.indexdb, e))


script = Script()

c = script.add_subcommand(InfoCommand('info', 'Show playing track information'))
c.add_argument('-v', '--verbose', action='store_true', help='Verbose messages')

c = script.add_subcommand(PlayCommand('play', 'Play/pause/jump to file'))
c.add_argument('track', nargs='?', help='Track to play')

c = script.add_subcommand(StopCommand('stop', 'Stop playback'))

c = script.add_subcommand(PreviousTrackCommand('previous', 'Play previous tracks'))
c = script.add_subcommand(NextTrackCommand('next', 'Play next tracks'))

c = script.add_subcommand(ShuffleModeCommand('shuffle', 'Toggle or show suffle mode'))
c.add_argument('mode',  nargs='?', choices=('enable', 'disable', ), help='Enable or disable shuffle mode')

c = script.add_subcommand(VolumeCommand('volume', 'Adjust or show playback volume'))
c.add_argument('volume',  nargs='?', help='Value to set')

c = script.add_subcommand(UpdateIndexCommand('update-index', 'Update track index database'))

args = script.run()
