#!/usr/bin/env python
#
#   ConVirt   -  Copyright (c) 2008 Convirture Corp.
#   ======
#
# ConVirt is a Virtualization management tool with a graphical user
# interface that allows for performing the standard set of VM operations
# (start, stop, pause, kill, shutdown, reboot, snapshot, etc...). It
# also attempts to simplify various aspects of VM lifecycle management.
#
#
# This software is subject to the GNU General Public License, Version 2 (GPLv2)
# and for details, please consult it at:
#
#    http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
# 
#
#


import gtk, gtk.glade, gobject
import re,pprint

from convirt.client.dialogs import showmsg,cb_showmsg, show_wait_cursor, hide_wait_cursor, confirmation
from convirt.client.dialogs import ApplianceLogos, file_selection
import convirt.core.appliance.xva
from convirt.core.model.ImageStore import ImageStore, ImageUtils
from convirt.client.TreeViewTooltips import TreeViewTooltips
from convirt.client.TaskProgressWnd import TaskProgressWnd
from convirt.core.utils.utils import Worker
from convirt.client.ui_utils import init_combo, get_value, set_value
xva = convirt.core.appliance.xva

class ColumnToolTip(TreeViewTooltips):
    
    def __init__(self, tip_column):
        self.tip_col = tip_column
        # call base class init
        TreeViewTooltips.__init__(self)
        
    def get_tooltip(self, view, column, path):
        if column is self.tip_col:
            model = view.get_model()
            if model:
                iter = model.get_iter(path)
                tooltip = ""
                if iter :
                    tooltip = model.get_value(iter,ApplianceList.SHORT_DESC)
                    if not tooltip:
                        tooltip = model.get_value(iter,ApplianceList.DESC)

                    return tooltip

    def location(self, x, y, w, h):
        # rename me to "location" so I override the base class
        # method.  This will demonstrate being able to change
        # where the tooltip window popups, relative to the
        # pointer.

        return x + 10, y



# encapsulates Appliance listing dialogs
class ApplianceList:

    (PROVIDER,TITLE,PACKAGE,ARCH,PAE,SIZE_MB,SIZE,UPDATED,DESC,SHORT_DESC,APPLIANCE_ENTRY) = range(11)
    initialized = False

    def __init__(self, wtree, appliance_store, image_store,
                 import_appliance_dlg):
        """ Constructor"""
        self.dialog = wtree.get_widget("appliance_dialog")
        # the list view
        self.list_view = wtree.get_widget("appliance_listview")

        # search widgets
        self.provider_combo = wtree.get_widget("provider_comboboxentry")
        self.package_combo = wtree.get_widget("package_comboboxentry")
        self.arch_combo = wtree.get_widget("arch_comboboxentry")
        self.title_entry = wtree.get_widget("appliance_name")
        self.pae_checkbox = wtree.get_widget("pae_checkbutton")
        self.search_button = wtree.get_widget("search_button")


        #self.list_view.set_activates_default(True)
        #self.dialog.set_default_response(gtk.RESPONSE_OK)

        
        # set default response
        self.dialog.set_default_response(gtk.RESPONSE_OK)

        # state variables
        self.list_model = None
        self.appliance_store = appliance_store
        self.image_store = image_store
        self.image_group = None
        
        self.import_dialog = import_appliance_dlg 
        self.parentwin = None

        # state of the search bar
        self.srch_provider = None
        self.srch_title = None
        self.srch_package = None
        self.srch_pae = False
        self.srch_arch = None
        
        rt_textrenderer = gtk.CellRendererText()
        rt_textrenderer.set_property("xalign", 1.0)

        c_textrenderer = gtk.CellRendererText()
        c_textrenderer.set_property("xalign", 0.5)

        # lets populate the colums

        # ENABLE THIS FOR PROVIDER ICON
        pbrenderer = gtk.CellRendererPixbuf()
        column = gtk.TreeViewColumn(" ", pbrenderer)
        column.set_cell_data_func(pbrenderer, self.get_provider_pixbuf)
        self.list_view.append_column(column)
        
        lt_textrenderer = gtk.CellRendererText()
        lt_textrenderer.set_property("xalign", 0.0)

        column = gtk.TreeViewColumn("Provider", lt_textrenderer, text=self.PROVIDER)
        column.set_clickable(True)
        column.set_sort_column_id(self.PROVIDER)
        column.set_resizable(True)
        self.list_view.append_column(column)

        
        textrenderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Name", textrenderer, text=self.TITLE)
        column.set_clickable(True)
        column.set_sort_column_id(self.TITLE)
        column.set_resizable(True)
        # tool tip
        self.stat_view_tt = ColumnToolTip(column)
        self.stat_view_tt.add_view(self.list_view)

        self.list_view.append_column(column)
        
        textrenderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Package", textrenderer, text=self.PACKAGE)
        column.set_clickable(True)
        column.set_sort_column_id(self.PACKAGE)
        column.set_resizable(True)
        self.list_view.append_column(column)

        textrenderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Arch", rt_textrenderer , text=self.ARCH)
        column.set_clickable(True)
        column.set_sort_column_id(self.ARCH)
        column.set_resizable(True)
        self.list_view.append_column(column)
        
        textrenderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("PAE", c_textrenderer , text=self.PAE)
        column.set_clickable(True)
        column.set_sort_column_id(self.PAE)
        column.set_resizable(True)
        self.list_view.append_column(column)

        
        textrenderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Size", rt_textrenderer , text=self.SIZE_MB)
        column.set_clickable(True)
        column.set_sort_column_id(self.SIZE)
        column.set_resizable(True)
        self.list_view.append_column(column)
        
        textrenderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Updated", textrenderer, text=self.UPDATED)
        column.set_clickable(True)
        column.set_sort_column_id(self.UPDATED)
        column.set_resizable(True)
        self.list_view.append_column(column)
        
        
        self.list_model = gtk.TreeStore(gobject.TYPE_STRING, # PROVIDER
                                        gobject.TYPE_STRING, # TITLE
                                        gobject.TYPE_STRING, # PACKAGE
                                        gobject.TYPE_STRING, # ARCH
                                        gobject.TYPE_STRING, # PAE
                                        gobject.TYPE_STRING, # SIZE_MB
                                        gobject.TYPE_INT, # SIZE
                                        gobject.TYPE_STRING, # UPDATED
                                        gobject.TYPE_STRING, # DESC
                                        gobject.TYPE_STRING, # SHORT_DESC
                                        gobject.TYPE_PYOBJECT) # APPLIANCE_ENTRY

        
        self.list_view.set_model(self.list_model)

        self.list_model.set_sort_column_id(1, gtk.SORT_ASCENDING)


        # setup handlers
        if not ApplianceList.initialized:
            self.title_entry.connect("key-press-event",self.on_title_search_key_pressed)
            self.dialog.connect("delete-event",self.dialog.hide_on_delete )
            
            wtree.signal_connect("on_appliance_list_import_clicked",
                                 self.on_import_button_clicked)
            wtree.signal_connect("on_appliance_list_cancel_clicked",
                                 self.on_cancel_button_clicked)
            wtree.signal_connect("on_appliance_list_search_clicked",
                                 self.on_search_button_clicked)
            wtree.signal_connect("on_appliance_list_import_other_clicked",
                                 self.on_import_other_button_clicked)

            ApplianceList.initialized = True


    def on_title_search_key_pressed(self, widget, event,data=None):
        if event.keyval == 65293 : # enter key pressed
            self.on_search_button_clicked(widget)
        
    def get_provider_pixbuf(self,column,cell,model,iter):
        a_info = model.get_value(iter, self.APPLIANCE_ENTRY)
        if a_info:
            provider_id = a_info["provider_id"]
            pb = ApplianceLogos.get_provider_logo(self.appliance_store,
                                                  provider_id)
            cell.set_property('pixbuf', pb) 

    def init_provider_combo(self):
        feeds = self.appliance_store.get_appliance_feeds()
        model = self.provider_combo.get_model()
        model.clear()

        self.provider_combo.append_text("Any")
        for feed_name in feeds:
            self.provider_combo.append_text(feed_name)

    def init_package_combo(self):
        packages = self.appliance_store.get_all_packages()
        packages.sort()
        
        model = self.package_combo.get_model()
        model.clear()

        self.package_combo.append_text("Any")
        for package in packages:
            self.package_combo.append_text(package)

    def init_arch_combo(self):
        archs = self.appliance_store.get_all_archs()
        archs.sort()
        model = self.arch_combo.get_model()
        model.clear()

        self.arch_combo.append_text("Any")
        for arch in archs:
            self.arch_combo.append_text(arch)


    def reset_search(self):
        self.srch_provider = None
        self.srch_title = None
        self.srch_package = None
        self.srch_pae = False
        self.srch_arch = None
        


    def show(self, widget, group_id = None, parentwin = None):

        self.parentwin = parentwin
        self.image_group = self.image_store.get_image_group(group_id)
        
        if parentwin:
            self.dialog.set_transient_for(parentwin)
            self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)

        try:
            show_wait_cursor()
            self.reset_search()
            self.populate_list()
            self.init_provider_combo()
            self.init_package_combo()
            self.init_arch_combo()
        finally:
            hide_wait_cursor()

        self.provider_combo.set_active(0)
        self.package_combo.set_active(0)
        self.arch_combo.set_active(0)

        self.title_entry.set_text("")
        self.pae_checkbox.set_active(False)

        #self.list_view.set_cursor((0,))
        self.list_view.grab_focus()
        self.dialog.show()
        #ret = self.dialog.run()
        #return ret

    # button handlers
    def on_import_other_button_clicked(self, widget):
        ret = self.import_dialog.show(widget, appliance_entry = None,
                                      image_name = None, image_group = self.image_group,
                                      mode="new_appliance",
                                      parentwin = self.dialog)

    
    def on_import_button_clicked(self, widget):
        """   Import the appliance  """
        selection = self.list_view.get_selection()
        treemodel, treeiter = selection.get_selected()
        if treeiter:
            appliance_entry = treemodel.get_value(treeiter,
                                                  self.APPLIANCE_ENTRY)
                                     
            #pprint.pprint(appliance_entry)
            
            # get the image name from the user.
            # if the image name exists ask him if it is ok to overwrite.
            title = appliance_entry["title"]
            #title = title.lower()
            image_name = re.sub(ImageStore.INVALID_CHARS_EXP,'_', title)
            self.import_dialog.show(widget, appliance_entry, image_name, self.image_group,
                                    parentwin = self.dialog)
        else:
            showmsg("Please select an appliance to import.")
            return
        #self.dialog.hide()
        
    def on_cancel_button_clicked(self, widget):
        """  Cancel on the dialog """
        self.dialog.hide()

    def on_search_button_clicked(self, widget):
        """  Search on the dialog """
        # save the state of the search criteria
        self.srch_provider = self.provider_combo.get_active_text()
        self.srch_title = self.title_entry.get_text()
        self.srch_arch  = self.arch_combo.get_active_text()
        self.srch_pae   = self.pae_checkbox.get_active()
        self.srch_package = self.package_combo.get_active_text()
        self.populate_list()


    def comp(self, ctx, item, srch, exact=True):
        if exact :
            ret = ((not srch) or (srch and srch.lower() == "any") or \
               (srch and item and str(item).lower() == str(srch).lower()))
        else:
            ret = ((not srch) or (srch and srch.lower() == "any") or \
                   (srch and item and str(item).lower().find(str(srch).lower()) > -1))
        #print ctx, ret, "[",srch,"]","{", item,"}"
        return ret
         
                    
    # Populate the appliance list from the information from the
    # appliance store.
    # take care of the search criteria
    def populate_list(self):
        self.list_model.clear()
        feeds = self.appliance_store.get_appliance_feeds()
        for feed_name in feeds:
            a_list = self.appliance_store.get_appliances_list(feed_name)
            for a_info in a_list:
                if not self.comp("provider",a_info["provider"],
                                 self.srch_provider, exact=False):
                    continue

                title = a_info["title"]
                if not self.comp("title", title,self.srch_title, exact=False):
                    continue

                size = int(a_info["size"])
                size_mb = "%12.1f" %  (size / (1024 * 1024)) + " MB"

                package = a_info["type"]
                arch    = a_info["arch"]
                pae     = a_info["PAE"]
                provider = a_info["provider"]
                
                # trick for boolean PAE
                srch_pae = self.srch_pae == True or ""

                if not self.comp("package", package, self.srch_package) or \
                       not self.comp("arch", arch, self.srch_arch) or \
                       not self.comp("pae", pae, str(srch_pae)):
                    continue

                desc = a_info.get("description")
                if not desc:
                    desc = ""

                short_desc = a_info.get("short_description")
                if not short_desc:
                    short_desc = ""

                if pae == "True":
                    pae_str = 'Y'
                else:
                    pae_str = 'N'

                if arch == "x86_64":
                    pae_str = ""
                

                iter = self.list_model.insert_before(None, None)
                self.list_model.set(iter,
                                    self.PROVIDER,provider,
                                    self.TITLE,title,
                                    self.PACKAGE,package,
                                    self.ARCH, arch,
                                    self.PAE, pae_str,
                                    self.SIZE_MB, size_mb,
                                    self.SIZE, size,
                                    self.UPDATED,a_info["updated"],
                                    self.DESC, desc,
                                    self.SHORT_DESC, short_desc,
                                    self.APPLIANCE_ENTRY,a_info
                                    )


    
        
# Class for out of band import as well as used as confirmation dialog
# from the list dialog.
import traceback
class ImportApplianceDlg:
    initialized = False
    def __init__(self, wtree, left_nav,
                 local_node, appliance_store, image_store, registry):
        """ Constructor"""
        self.dialog = wtree.get_widget("appliance_import")

        # widgets
        self.provider_combo = wtree.get_widget("ia_provider_combo")
        self.package_combo = wtree.get_widget("ia_package_combo")
        self.arch_combo = wtree.get_widget("ia_arch_combo")
        self.platform_combo = wtree.get_widget("ia_platform_combo")
        self.pae_checkbox = wtree.get_widget("ia_pae_checkbox")
        self.hvm_checkbox = wtree.get_widget("ia_hvm_checkbox")
        self.download_url = wtree.get_widget("ia_download_url")
        self.size_entry = wtree.get_widget("ia_size_entry")
        self.file_sel_button = wtree.get_widget("app_import_file_select_button")

        self.platform_label = wtree.get_widget("platform_label")
        self.size_label = wtree.get_widget("size_label")

        self.image_name   = wtree.get_widget("ia_image_name")
        self.image_group_combobox = wtree.get_widget("ia_image_group_combobox")

        self.download_url.set_activates_default(True)
        self.image_name.set_activates_default(True)
        # remove for now. we support only xen platform
        #self.platform_combo.hide()
        #self.platform_label.hide()

        self.init_platform_combo(registry)
        
        self.dialog.set_default_response(gtk.RESPONSE_OK)


        # state
        self.widget_list = ( self.provider_combo,
                             self.package_combo,
                             self.arch_combo,
                             self.platform_combo,
                             self.pae_checkbox,
                             self.hvm_checkbox,
                             self.download_url, 
                            # self.image_name,
                             self.file_sel_button,
                             self.size_entry )


        self.mode = "confirmation"
        self.appliance_entry = None
        self.appliance_store = appliance_store
        self.image_store = image_store
        self.local_node = local_node
        self.left_nav = left_nav

        self.parentwin = None

    
        self.image_liststore = gtk.ListStore(str, str)
        image_cell = gtk.CellRendererText()
        self.image_group_combobox.pack_start(image_cell, False)
        self.image_group_combobox.add_attribute(image_cell, "text", 0)
        self.image_group_combobox.set_model(self.image_liststore)

        # signal handlers
        if not ImportApplianceDlg.initialized:
            self.dialog.connect("delete-event",self.dialog.hide_on_delete )
            wtree.signal_connect("on_ia_ok_clicked",
                                 self.on_ok_button_clicked)
            wtree.signal_connect("on_ia_cancel_clicked",
                                 self.on_cancel_button_clicked)
            wtree.signal_connect("on_app_import_file_select_button_clicked",
                                 self.on_file_sel_button_clicked)

            ImportApplianceDlg.initialized = True


    def init_platform_combo(self, registry):
        p_map = {}
        for p, info in registry.get_platforms().iteritems():
            p_map[info["name"]] =  p
        init_combo(self.platform_combo, p_map)
            
            
        
    def init_provider_combo(self):
        feeds = self.appliance_store.get_appliance_feeds()
        feeds.sort()
        model = self.provider_combo.get_model()
        model.clear()

        for feed_name in feeds:
            self.provider_combo.append_text(feed_name)
        self.provider_combo.append_text("Other")

    def init_package_combo(self):
        packages = self.appliance_store.get_all_packages()
        packages.sort()
        
        model = self.package_combo.get_model()
        model.clear()

        for package in packages:
            self.package_combo.append_text(package)

    def init_arch_combo(self):
        archs = self.appliance_store.get_all_archs()
        archs.sort()
        model = self.arch_combo.get_model()
        model.clear()

        for arch in archs:
            self.arch_combo.append_text(arch)

    # Initialize the group combobox.
    # If the group is available, then select the group and disable the combobox.
    # If the group is not available, then let the user select the image group.       
    def init_image_group_combo(self, image_group):
        groups = self.image_store.image_groups
        model = self.image_group_combobox.get_model()        
        self.image_group_combobox.set_model(None)
        model.clear()

        i=0
        for igroup in groups:
            gname = groups[igroup].get_name()
            gid = groups[igroup].get_id()
            model.insert(i, [gname, gid])
            i = i + 1
            
        self.image_group_combobox.set_model(model)
        
        if image_group is not None:
            pos = groups.keys().index(image_group.get_id())
            if pos >= 0:
                self.image_group_combobox.set_active(pos)
            self.image_group_combobox.set_sensitive(False)
        else:
            self.image_group_combobox.set_active(0)
            self.image_group_combobox.set_sensitive(True)

    def get_active_text(self):
        model = self.image_group_combobox.get_model()
        active = self.image_group_combobox.get_active()
        if active < 0:
            return model[0]
        return model[active]
            

    def set_widgets(self,enable=True, editable = True):
        for widget in self.widget_list:
            if isinstance(widget, gtk.ComboBoxEntry):
                widget.child.set_editable(editable)
            elif isinstance(widget, gtk.CheckButton):
                widget.set_sensitive(editable)
            elif isinstance(widget, gtk.Button):
                widget.set_sensitive(editable)
            else:
                widget.set_editable(editable)
        for widget in self.widget_list:
            widget.set_sensitive(enable)
                    
    def set_size_widgets(self, editable=True):
        for w in (self.size_entry,):
            w.set_sensitive(editable)

        

    def show(self, widget, appliance_entry, image_name, image_group,
             mode="confirmation", parentwin = None):

        if parentwin:
            self.dialog.set_transient_for(parentwin)
            self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
            self.parentwin = parentwin
        else:
            self.parentwin = None

        self.init_provider_combo()
        self.init_package_combo()
        self.init_arch_combo()
        self.init_image_group_combo(image_group)


        self.mode = mode
        self.appliance_entry = appliance_entry
        if mode == "confirmation":
            # populate from appliance/download context
            if appliance_entry :
                self.download_url.set_text(appliance_entry["href"])
                self.image_name.set_text(image_name)
                self.provider_combo.child.set_text(appliance_entry["provider_id"])
                set_value(self.platform_combo,appliance_entry["platform"].lower())
                self.package_combo.child.set_text(appliance_entry["type"])
                self.arch_combo.child.set_text(appliance_entry["arch"])
                if appliance_entry["PAE"] and \
                       appliance_entry["PAE"].lower() == "true":
                    self.pae_checkbox.set_active(1)
                else:
                    self.pae_checkbox.set_active(0)

                if appliance_entry["is_hvm"] and \
                       appliance_entry["is_hvm"].lower() == "true":
                    self.hvm_checkbox.set_active(1)
                else:
                    self.hvm_checkbox.set_active(0)

                
                # size in MB
                self.size_entry.set_text(str(int(appliance_entry["size"]) / (1024 * 1024)))
            # disable all widget
            self.set_widgets(False, False)
            self.set_size_widgets(False)
                        
        else:
            self.set_widgets(True, True)
            self.set_size_widgets(False)
            # clear all widgets
            self.download_url.set_text("")
            self.image_name.set_text("")
##          self.provider_combo.child.set_text("")
##          self.platform_combo.child.set_text("")
##          self.package_combo.child.set_text("")
##          self.arch_combo.child.set_text("")

            self.provider_combo.set_active(0)
            self.platform_combo.set_active(0)
            self.package_combo.set_active(0)
            self.arch_combo.set_active(0)
            
            self.pae_checkbox.set_active(0)
            self.hvm_checkbox.set_active(0)
            self.size_entry.set_text("")

            # there must be a way to just iterate and reset everything.
            #for widget in self.widget_list:
            #    widget.__class__
            #    widget.set_text("") 
        
        
        self.dialog.show()
        #ret = self.dialog.run()
        #return ret

    def on_file_sel_button_clicked(self, widget):
        # popup the file selection
        result, filename = file_selection(self.appliance_store.local_node,
                                          "Select Appliance", "open",
                                          parentwin = self.parentwin,
                                          force_local = True)


        if result:
            self.download_url.set_text(filename)

    def on_ok_button_clicked(self, widget):
        # get the values and kick off the import

        if self.mode == "confirmation":
            # only text and override are editable.
            image_name = self.image_name.get_text()
        else:
            
            # gather information from the UI
            # build a appliance entry
            # pass it on
            self.appliance_entry = {}
            self.appliance_entry["href"] = self.download_url.get_text()
            self.appliance_entry["type"] = self.package_combo.child.get_text()
            self.appliance_entry["arch"] = self.arch_combo.child.get_text()
            self.appliance_entry["PAE"] = self.pae_checkbox.get_active()
            self.appliance_entry["is_hvm"] = self.hvm_checkbox.get_active()
            self.appliance_entry["size"] = self.size_entry.get_text()
            self.appliance_entry["provider_id"] = self.provider_combo.child.get_text()
            self.appliance_entry["platform"] = get_value(self.platform_combo)
            image_name = self.image_name.get_text()
            self.appliance_entry["title"] = image_name


            if self.appliance_entry["provider_id"].lower() == "jumpbox":
                self.appliance_entry["is_hvm"] = "True"

            # Get provider url and logo url.
            provider_id = self.appliance_entry["provider_id"]
            p_url = self.appliance_store.get_provider_url(provider_id)
            self.appliance_entry["provider_url"] = p_url
            p_logo_url = self.appliance_store.get_logo_url(provider_id)
            self.appliance_entry["provider_logo_url"] = p_logo_url
            self.appliance_entry["link"] = ""
            self.appliance_entry["description"] = "Manually imported appliance. Plese use 'Edit Description' menu to put appropriate description here."
            if self.appliance_store.get_provider(provider_id):
                self.appliance_entry["provider"] = self.appliance_store.get_provider(provider_id)
            else:
                self.appliance_entry["provider"] = provider_id

        # do some basic validation
       
        if not self.appliance_entry["href"] :
            showmsg("Please specify a valid download url.")
            return

        if image_name:
            image_name = image_name.strip()
           
        if not image_name :
            showmsg("Please specify an image name.")
            return
 
# mImage name can contain special chars. 
#        if re.sub(ImageStore.INVALID_CHARS_EXP,"", image_name) != image_name:
#            showmsg("Image name can not contain any special chars %s" % \
#                    ImageStore.INVALID_CHARS)
#            return

 
        platform = self.appliance_entry["platform"]
        #if platform  and platform.lower() != "xen":
        #    showmsg("Invalid Platform %s : This version supports only Xen" % platform)
        #    return

        type = self.appliance_entry["type"]
        if type.lower() not in ("xva", "file_system", "jb_archive"):
            showmsg("Invalid Package type %s: supported package types are XVA, FILE_SYSTEM. JB_ARCHIVE" % type)
            return

        # Pass group id to the import dialogbox. We should be able to select the group.
        # When we can select the group, remove this.
        (group_name, group_id) = self.get_active_text()
        self.group_id = group_id
        image_group = self.image_store.get_image_groups()[self.group_id]

        # check if the image name exists.
        force = False

        if image_group.image_exists_by_name(image_name):
            if confirmation("Image already exists. Do you want to overwrite it ?"):
                force = True
                img = image_group.get_image_by_name(image_name)
                self.image_store.delete_image(self.group_id, img.get_id())
            else:
                return


        try:
            # Create a new image and add it to the group.
            img = self.image_store.create_image(self.group_id, image_name,
                                                platform.lower())

            try:
                #show_wait_cursor(self.dialog)
                title = self.appliance_entry.get("title")
                if not title:
                    title = ""
                    
                progress = TaskProgressWnd("Import : " + title)
                
                progress.show(parentwin = self.dialog)
                suc_msg = title + "Appliance imported succesfully"
                
                if self.appliance_entry["type"].lower() == "xva":
                    w= Worker(lambda : xva.import_appliance(self.local_node,
                                                            self.appliance_entry,
                                                            self.image_store,
                                                            self.group_id,
                                                            img,
                                                            force,
                                                            progress),
                              lambda ret=None: self.suc_callback(progress, ret, image_group.get_name()),
                              lambda ex=None: self.failure_cb(self.image_store,
                                                              self.group_id,
                                                              img.get_id(),
                                                              progress, ex))
                    w.start()
                else:
                    w = Worker(lambda : ImageUtils.import_fs(self.local_node,
                                         self.appliance_entry,
                                         self.image_store,
                                         self.group_id,
                                         img,
                                         force,progress),
                               lambda ret=None:self.suc_callback(progress, ret, image_group.get_name()),
                               lambda ex=None: self.failure_cb(self.image_store,
                                                               self.group_id,
                                                               img.get_id(),
                                                               progress, ex))
                    w.start()

            finally:
                pass
                #hide_wait_cursor(self.dialog)

            ## self.image_store.re_initialize()
            ## self.left_nav.refresh_nodes()
            ## self.left_nav.set_selection("Image Store",
            ## self.left_nav.IMAGE_STORE,
            ## op="row-activated")

            #showmsg("Appliance imported successfully to the Image Store.")

        except Exception, ex:
            traceback.print_exc()
            showmsg(ex)
            return

        self.dialog.hide()
        
    def on_cancel_button_clicked(self, widget):
        self.dialog.hide()


    def failure_cb(self, image_store, image_group_id,
                   image_id, progress, ex = None):
        msg = None
        if ex:
            msg = str(ex)
        # All safe ops so no need to get gtk lock
        if progress:
            progress.update(progress.CANCELED,msg)

        if image_store and image_id:
            image_store.delete_image(image_group_id, image_id) 

    def suc_callback(self, progress, ret, group_name):
        if progress:
            progress.update(progress.COMPLETE,
                            "Appliance imported successfully to the image image group: " + group_name)
        try:
            gtk.gdk.threads_enter()
            self.image_store.re_initialize()
            self.left_nav.refresh_nodes()
            self.left_nav.set_selection("Image Store",
                                        self.left_nav.IMAGE_STORE,
                                        op="row-activated")
        finally:
            gtk.gdk.threads_leave()


