# Copyright (C) 2008-2009 LottaNZB Development Team
# 
# 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; version 3.
# 
# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

import gtk

import logging
log = logging.getLogger(__name__)

from kiwi.ui.delegates import Delegate
from kiwi.ui.objectlist import Column

from lottanzb.gui import modes as mode_gui
from lottanzb.core import App
from lottanzb.util import get_hellanzb_cmd, _
from lottanzb.modes import mode_list, base
from lottanzb.backend import WrongPasswordError

class Dialog(Delegate):
    gladefile = "mode_selection_dialog"
    
    def __init__(self, error=None):
        self.mode_manager = App().mode_manager
        self.modes = {}
        self.config_views = {}
        
        Delegate.__init__(self)
        
        self.error.connect("notify::label", self.on_error_changed)
        self.mode_list.set_columns([
            Column("icon", use_stock=True, data_type=gtk.gdk.Pixbuf),
            Column("short", expand=True)
        ])
        
        for cls in mode_list:
            name = cls.get_name()
            mode_config = self.mode_manager.config[name].deep_copy()
            mode = cls(mode_config)
            
            self.modes[name] = mode
            self.mode_list.append(mode)
            self.config_views[name] = getattr(mode_gui, name).ConfigView
        
        self.register_validate_function(self.validity)
        
        hint, self.suggested_mode = self.get_hint()
        
        self.select_mode(self.mode_manager.config.active or self.suggested_mode)
        self.hint.set_text(hint)
        
        if error:
            self.error.set_text(error)
        
        self.force_validation()
    
    def validity(self, valid):
        self.save.set_sensitive(valid)
    
    def select_mode(self, mode):
        if isinstance(mode, base.Mode):
            if not mode in self.modes:
                mode = self.modes[mode.get_name()]
        else:
            mode = self.modes[mode]
        
        self.mode_list.select(mode)
    
    def on_mode_list__selection_changed(self, widget, mode):
        old_slave = self.get_slave("mode")
        
        if old_slave:
            if old_slave.mode is mode:
                return
            else:
                self.detach_slave("mode")
        
        self.attach_slave("mode", self.config_views[mode.get_name()](mode))
        
        self.error.set_text("")
        self.name.set_markup("<b>%s</b>" % mode.title)
        self.description.set_text(mode.description)
    
    def on_save__clicked(self, widget):
        def on_failure(exception):
            log.error(str(exception))
            self.error.set_text(str(exception))
            
            self.save.set_sensitive(True)
            gtk.main_iteration()
        
        def on_sucess():
            App().config.save()
            self.toplevel.destroy()
        
        self.save.set_sensitive(False)
        gtk.main_iteration()
        
        try:
            self.mode_manager.set_mode(self.mode_list.get_selected(),
                on_success=on_sucess,
                on_failure=on_failure
            )
        except Exception, e:
            on_failure(e)
    
    def on_cancel__clicked(self, widget):
        self.toplevel.destroy()
    
    def on_error_changed(self, widget, *args):
        self.error_container.set_property("visible", bool(widget.get_text()))
    
    def get_hint(self):
        try:
            App().backend.checkConnection("localhost", 8760, "")
        except WrongPasswordError:
            running = True
        except:
            running = False
        else:
            running = True
        
        if running:
            try:
                assert self.modes["standalone"].usesCorrectConfigFile()
            except:
                return _("The HellaNZB daemon seems to be already running. "
                    "The local front-end mode might be the most appropriate "
                    "usage mode for you."), self.modes["local_frontend"]
            else:
                return _("LottaNZB is currently in stand-alone mode. "
                    "HellaNZB is already running and uses the configuration "
                    "file managed by LottaNZB."), self.modes["standalone"]
        else:
            if get_hellanzb_cmd():
                return _("No HellaNZB daemon seems to be listening on the "
                    "default port, so it's most likely not running. "
                    "The stand-alone mode might be the most appropriate usage "
                    "mode for you."), self.modes["standalone"]
            else:
                return _("The HellaNZB executable could not be found. "
                    "This could mean that it isn't installed on your system "
                    "or that you've installed it in a non-standard way. "
                    "If you want to control a HellaNZB daemon on another "
                    "computer, select the remote front-end usage mode. "
                    "Otherwise, make sure HellaNZB is installed properly."), \
                    self.modes["remote_frontend"]
