# -*- coding: UTF-8 -*-
#
#  AddWizards.py : User friendly configuration tool
#  Copyright (C) 2007 Mertens Florent <flomertens@gmail.com>
#
#  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
#

from xml.sax.saxutils import escape as escape_mkup

import pygtk
pygtk.require("2.0")
import gtk
from SimpleGladeApp import SimpleGladeApp
from gettext import gettext as _

from config import *
from Config import Config

from Fstab.FstabHandler import *

            
class AddWizard(SimpleGladeApp) :
    ''' Provide a friendly guy to configure new devices '''

    def __init__(self, devices = None, parent = None, disk = None, auto = False, log = True):
    
        SimpleGladeApp.__init__(self, GLADEFILE, "dialog_new", domain = PACKAGE)
        self.dialog_new.set_title("")
        if parent : 
            self.dialog_new.set_transient_for(parent)
            
        # Setup gui and connect events
        self.setup_treeview()
        self.ok_button.connect("clicked", self.on_ok_clicked)
        self.cancel_button.connect("clicked", self.on_quit)
        self.dialog_new.connect("destroy", self.on_quit)
        self.auto_button.connect("clicked", self.on_auto_clicked)
        gtk.gdk.threads_init()
        
        # Create FstaHandler object, set options
        self.conf = Config()
        self.log = log
        if not disk :
            naming = self.conf.get("General", "fstab_naming")
            backend = self.conf.get("General", "backend")
            disk = FstabHandler(FSTAB, naming = naming, backend = backend)
            for entry in disk.get_new() :
                ntfs_driver = self.conf.get("General", "ntfs_driver")
                if entry["FS_TYPE"] == "ntfs" and not entry["FSTAB_TYPE"] == ntfs_driver:
                    disk.set(entry, type = ntfs_driver)
        self.disk = disk
        self.disk.set_mode("virtual")
        detected = " ".join([ k["DEVICE"] for k in self.disk.get_all() ])
        self.conf.set("Detected Device", "detected", detected)
        
        # Add new devices in the treeview
        self.no_path = _("<Enter a mount point>")
        self.entries = []
        for entry in self.disk.get_new() :
            if not self.disk.get_duplicate(entry) and ( devices and entry["DEVICE"] not in devices ) :
                continue
            self.entries.append(entry)
            if not entry.has_key("FS_LABEL_SAFE") and not entry.get_is_mounted() :
                self.tree_store.append((False, entry["DEVICE"], self.no_path))
            else : 
                self.disk.configure(entry)
                self.tree_store.append((True, entry["DEVICE"], entry["FSTAB_PATH"]))

        if auto :
            self.auto_configure()
        else :
            self.dialog_new.show()
            
    def setup_treeview(self) :
        ''' treeview setup '''
 
        renderer= gtk.CellRendererToggle()
        renderer.set_property("activatable", True)
        renderer.connect("toggled", self.on_toggled)
        column = gtk.TreeViewColumn(_("Add"), renderer, active=0)
        self.treeview.append_column(column)
        
        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Device"), renderer, text=1)
        self.treeview.append_column(column)
        
        renderer = gtk.CellRendererText()
        renderer.set_property("editable", True)
        renderer.connect("edited", self.on_edit)
        column = gtk.TreeViewColumn(_("Mount Point"), renderer, text=2)
        self.treeview.append_column(column)
        
        self.tree_store = gtk.ListStore(bool, str, str)
        self.treeview.set_model(self.tree_store)
            
    def on_toggled(self, renderer, path) :

        self.set_state(path, not self.tree_store[path][0])
        
    def set_state(self, path, state) :
    
        entry = self.entries[int(path)]
        if state :
            self.disk.configure(entry)
            self.tree_store[path][0] = True
        else :
            self.disk.unconfigure(entry)
            self.tree_store[path][0] = False
        self.check_ok_button()
      
    def on_edit(self, renderer, path_string, path) :
        ''' accept only path in /media. '''

        entry = self.entries[int(path_string)]
        if path == "" or path == self.no_path :
            self.tree_store[path_string][2] = self.no_path
            self.set_state(path_string, False)
            self.check_ok_button()
            return
        if not path[:len("/media/")] == "/media/" :
            if path[0] == "/" :
                dialog("warning", _("Formatting error"), \
                _("<i>%s</i> contains an invalid character.\n" \
                "Mount point should be in /media/. Alternatively, you can " \
                "enter a simple name, like <i>disk</i>.") % escape_mkup(path), \
                parent = self.dialog_new)
                return
            path = "/media/" + path   
        self.disk.set(entry, path = path)
        self.set_state(path_string, True)
        self.tree_store[path_string][2] = entry["FSTAB_PATH"]
        self.check_ok_button()
        
    def check_ok_button(self) :
        ''' make ok sensitive when all selected path are ok '''
    
        for path in range(len(self.tree_store))  :
            if not self.tree_store[path][2][0] == "/" and self.tree_store[path][0] :
                self.ok_button.set_sensitive(False)
                return
        self.ok_button.set_sensitive(True)
        
    def on_ok_clicked(self, button) :
    
        self.disk.apply_now()
        if self.log :
            self.disk.savelog()
        self.cancel_button.clicked()
        
    def on_auto_clicked(self, button) :
    
        self.auto_configure()
        self.cancel_button.clicked()
        
    def auto_configure(self) :
    
        for entry in self.entries :
            self.disk.configure(entry)
        self.disk.apply_now()
        if self.log :
            self.disk.savelog()
     
    def on_quit(self, button) :

        self.dialog_new.hide()
        self.disk.set_mode("real")
        gtk.main_quit() 
        

def probe_new_device() :
    ''' Probe for new devices '''

    fstab = FstabHandler(FSTAB)
    detected = Config().get("Detected Device","detected").strip().split()
    return [ k for k in fstab.get_new() if k["DEVICE"] not in detected ]

