"""
Pympc is a client for Music Player Daemon.
Copyright (C) 2004  Magnus Bjernstad <bjernstad@gmail.com>

This file is part of Pympc.

Pympc 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.

Pympc 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 Pympc; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""
import os, sys, pympc, ConfigParser

class Config:
    # Default config values
    v = {'global.status_format':    'status_format = [%artist% - ]%title%|%path%',
         'global.music_directory':  '',
         'global.host':             'localhost',
         'global.port':             6600,
         'global.password':         '',
         'global.time_format':      'elapsed',
         'gui.tabs':                'playlist library find cover',
         'gui.theme':               'default',
         'gui.row1':                'prev play stop next volume random repeat',
         'gui.row2':                'time progress',
         'playlist.format':         'path,300',
         'playlist.active_color':   'tomato',
         'playlist.show_filter':    True,
         'search.incremental':      True,
         'state.win_width':         500,
         'state.win_height':        600,
         'state.win_pos_x':         0,
         'state.win_pos_y':         0,
         'state.mode':              'normal',
         'state.tab':               'playlist'}
    
    def __get_option(self, c, section, option):
        if c.has_option(section, option):
            self.v[section + '.' + option] = c.get(section, option)
    def __get_option_bool(self, c, section, option):
        if c.has_option(section, option):
            self.v[section + '.' + option] = c.getboolean(section, option)
    def __get_option_int(self, c, section, option):
        if c.has_option(section, option):
            self.v[section + '.' + option] = c.getint(section, option)
    def __get_option2(self, c, section, option, type):
        if c.has_option(section, option):
            if type == str:
                self.v[section + '.' + option] = c.get(section, option)
            elif type == int:
                self.v[section + '.' + option] = c.getint(section, option)
            elif type == bool:
                self.v[section + '.' + option] = c.getboolean(section, option)


    def __init__(self):
        c = ConfigParser.RawConfigParser()
        # Static config
        try:
            c.read(os.path.expanduser('~/.pympcrc'))
        except ConfigParser.Error:
            sys.stderr.write('Syntax error in config file.\n')
            raise SystemExit

        for x in self.v:
            section, option = x.split('.')
            self.__get_option2(c, section, option, type(self.v[x]))

        self.v['playlist.format'] = self.__translate_format_string(
                self.v['playlist.format'])
        # State file
        try:
            c.read(os.path.expanduser('~/.pympc.state'))
        except ConfigParser.Error:
            sys.stderr.write('Syntax error in state file.\n')
            return

        for x in self.v:
            section, option = x.split('.')
            self.__get_option2(c, section, option, type(self.v[x]))

        self.find_theme_dir()

    def __translate_format_string(self, string):
        """
        Translates a format string at the form
            artist,200;title,200
        to the corresponding form
            [('artist', 200), ('title', 200)]
        """
        try:
            cols = string.split(';')
            names =  [    x.split(',')[0]  for x in cols]
            widths = [int(x.split(',')[1]) for x in cols]
            # The config file convention is to use 'path' to signify the file name
            try: names[names.index('path')] = 'file'
            except ValueError: pass
            return [(names[x], widths[x]) for x in range(len(names))]
        except Exception:
            sys.stderr.write('Syntax error in playlist format\n')
            raise SystemExit

    def save_state(self, app):
        w = app.w
        c = ConfigParser.RawConfigParser()
        pos = w('window').get_position()
        c.add_section('state')
        c.set('state', 'win_pos_x', pos[0])
        c.set('state', 'win_pos_y', pos[1])
        size = w('window').get_size()
        if w('expander').get_expanded() == False:
            c.set('state', 'mode', 'mini')
            c.set('state', 'win_width', size[0])
            c.set('state', 'win_height', app.window_size[1])
        else:
            c.set('state', 'mode', 'normal')
            c.set('state', 'win_width', size[0])
            c.set('state', 'win_height', size[1])
        try:
            c.set('state', 'tab', pympc.TABS[w('notebook').get_current_page()])
        except KeyError:
            c.set('state', 'tab', 'playlist')
        config_file = os.path.expanduser('~/.pympc.state')
        fo = file(config_file, 'w')
        c.write(fo)
        fo.close()

    def apply_state_file(self, app):
        v = self.v
        w = app.w
        try:
            w('window').move(v['state.win_pos_x'], v['state.win_pos_y'])
        except KeyError:
            pass
        w('window').resize(v['state.win_width'],
                v['state.win_height'])
        app.pl.set_columns(v['playlist.format'])
        w('vbox').show_all()
        if v['state.mode'] == 'mini':
            w('expander').emit('activate')
        app.set_current_page(v['state.tab'])
        w('window').show()

    def find_theme_dir(self):
        # Try sys.prefix/share/themes first
        self.v['global.theme_dir'] = os.path.join(sys.prefix,
                'share', 'pympc', 'themes', self.v['gui.theme']) + os.sep
        try:
            assert(os.path.isdir(self.v['global.theme_dir']))
            return
        except AssertionError:
            pass
        # Then the current dir
        self.v['global.theme_dir']= os.path.join(os.path.split(__file__)[0],
                'themes', self.v['gui.theme']) + os.sep
        try:
            assert(os.path.isdir(self.v['global.theme_dir']))
            return
        except AssertionError:
            pass
        sys.stderr.write('Theme "' + self.conf['gui.theme'] + '" not found.\n')
        raise SystemExit

