#!/usr/local/bin/python2.7

# Copyright (C) 2002 Martin Willemoes Hansen <mwh@sysrq.dk>
#
# Jump 'n Bump 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.
#
# Jump 'n Bump 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# Next two lines are a workaround for Debian bug 163794
import sys

import pygtk
pygtk.require('2.0')
import gtk
import gtk.glade
import gtk.gdk
import gobject
import os
import tempfile
import shutil
import gettext

RESOURCE_DIR = '/usr/local/share/jumpnbump'
BINARY_DIR = '/usr/local/bin'
UNPACK_BIN = '/usr/local/bin/jnbunpack'

application = "jumpnbump-menu"
gettext.install(application)


def populate_treeview():
    levels = []
    add_levels(levels, RESOURCE_DIR)
    add_levels(levels, os.path.expanduser("~/.jumpnbump/levels"))

    levels = sorted(levels, key=lambda level: level[0])

    COLUMN_LEVEL = 0
    COLUMN_DIR = 1
    store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)

    for level in levels:
        iter = store.append()
        store.set(iter, COLUMN_LEVEL, level[0], COLUMN_DIR, level[1])

    treeview.set_model(store)

    renderer = gtk.CellRendererText()
    treeview.append_column(gtk.TreeViewColumn(
        _('Level'), renderer, text=COLUMN_LEVEL))


def add_levels(levels, dir):
    try:
        for file in os.listdir(dir):
            if (file.endswith('.dat') or file.endswith('.DAT')):
                levels.append((file, dir))
    except OSError, err:
        print("%s not found (%s)." % (dir,  str(err)))


def standalone_mode(widget):
    disable_enable_level(1)
    disable_enable_server(0)
    num_clients.set_sensitive(0)
    nogore.set_sensitive(1)
    noflies.set_sensitive(1)


def client_mode(widget):
    disable_enable_level(1)
    disable_enable_server(1)
    num_clients.set_sensitive(0)
    nogore.set_sensitive(1)
    noflies.set_sensitive(1)


def server_mode(widget):
    disable_enable_level(1)
    disable_enable_server(0)
    num_clients.set_sensitive(1)
    nogore.set_sensitive(1)
    noflies.set_sensitive(1)


def disable_enable_server(setting):
    server_entry.set_sensitive(setting)
    player_num.set_sensitive(setting)


def disable_enable_level(setting):
    treeview.set_sensitive(setting)
    mirror.set_sensitive(setting)
    if (not setting):
        mirror.set_active(setting)


def level_changed(widget):
    model, iter = treeview.get_selection().get_selected()
    global choosen_level
    choosen_level = '%s/%s' % (model.get_value(iter, 1),
                               model.get_value(iter, 0))
    unpackdir = None
    try:
        unpackdir = tempfile.mkdtemp("", "jumpnbump-menu-")
        os.chdir(unpackdir)
        os.spawnlp(os.P_WAIT, UNPACK_BIN,
                   'unpack', choosen_level)
        os.spawnlp(os.P_WAIT, 'convert', 'convert', '-scale',
                   '50%', 'level.pcx', 'level_scaled.pcx')
        os.spawnlp(os.P_WAIT, 'convert', 'convert',
                   'level_scaled.pcx', 'level.png')
        image.set_from_file('level.png')
    except Exception, err:
        print err
    finally:
        if unpackdir != None:
            shutil.rmtree(unpackdir)

    image.show()


def about(widget):
    global about_dialog

    if (not about_dialog):
        gui = gtk.glade.XML(gladefile, 'about', domain=application)
        about_dialog = gui.get_widget('about')
        gui.signal_connect('ok', about_close)


def about_close(widget):
    global about_dialog

    about_dialog.destroy()
    about_dialog = None


def run(widget):
    if (standalone.get_active()):
        execute(*get_level() + common_options())
    elif (client.get_active()):
        execute('-player', str(player_num.get_value_as_int()),
                '-connect', server_entry.get_text(),
                *get_level() + common_options())
    else:
        execute('-server', str(num_clients.get_value_as_int()),
                *get_level() + common_options())


def get_level():
    level = []
    if (mirror.get_active()):
        level.append('-mirror')
    else:
        level.append('-dat')
        level.append(choosen_level)

    return level


def common_options():
    options = []

    if (fullscreen.get_active()):
        options.append('-fullscreen')
    if (nogore.get_active()):
        options.append('-nogore')
    if (double_res.get_active()):
        options.append('-scaleup')
    if (nosound.get_active()):
        options.append('-nosound')
    if (noflies.get_active()):
        options.append('-noflies')
    if (withmusic.get_active()):
        options.append('-musicnosound')
    if (mirror.get_active()):
        options.append('-mirror')

    return options


def execute(*cmd):
    try:
        os.spawnl(os.P_NOWAIT, BINARY_DIR + '/jumpnbump', 'jumpnbump', *cmd)
    except Exception, err:
        print err


def main():
    global gladefile

    global_gladefile = RESOURCE_DIR + '/jumpnbump_menu.glade'
    local_gladefile = './jumpnbump_menu.glade'

    if (os.access(global_gladefile, os.R_OK)):
        gladefile = global_gladefile
        del local_gladefile
    elif (os.access(local_gladefile, os.R_OK)):
        gladefile = local_gladefile
        del global_gladefile
    else:
        print 'Could not find the glade file'
        return 0

    gui = gtk.glade.XML(gladefile, 'main', domain=application)

    global about_dialog, choosen_level, standalone, client, server, treeview, \
        mirror, num_clients, server_entry, player_num, fullscreen, \
        nogore, double_res, nosound, noflies, withmusic, image

    about_dialog = None
    choosen_level = ''
    standalone = gui.get_widget('standalone')
    client = gui.get_widget('client')
    server = gui.get_widget('server')
    treeview = gui.get_widget('level_treeview')
    populate_treeview()
    mirror = gui.get_widget('mirror')
    num_clients = gui.get_widget('num_of_clients')
    server_entry = gui.get_widget('server_entry')
    player_num = gui.get_widget('player_num')
    fullscreen = gui.get_widget('fullscreen')
    nogore = gui.get_widget('nogore')
    double_res = gui.get_widget('double_res')
    nosound = gui.get_widget('nosound')
    noflies = gui.get_widget('noflies')
    withmusic = gui.get_widget('withmusic')
    image = gui.get_widget('image')

    gui.signal_autoconnect({'standalone_mode': standalone_mode,
                            'client_mode': client_mode,
                            'server_mode': server_mode,
                            'level_changed': level_changed,
                            'quit': lambda *args: gtk.main_quit(),
                            'run': run,
                            'about': about})

    gtk.main()

if __name__ == '__main__':
    main()
