#!/usr/bin/env python

# Copyright (c) 2012 Wind River Systems, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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

import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname( \
                                    os.path.abspath(__file__))), 'lib'))
try:
    import bb
except RuntimeError as exc:
    sys.exit(str(exc))

import gtk
import optparse
import pygtk

from bb.ui.crumbs.hobwidget import HobAltButton, HobButton
from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
from bb.ui.crumbs.hig.deployimagedialog import DeployImageDialog
from bb.ui.crumbs.hig.imageselectiondialog import ImageSelectionDialog

# I put all the fs bitbake supported here. Need more test.
DEPLOYABLE_IMAGE_TYPES = ["jffs2", "cramfs", "ext2", "ext3", "ext4", "btrfs", "squashfs", "ubi", "vmdk"]
Title = "USB Image Writer"

class DeployWindow(gtk.Window):
    def __init__(self, image_path=''):
        super(DeployWindow, self).__init__()

        if len(image_path) > 0:
            valid = True
            if not os.path.exists(image_path):
                valid = False
                lbl = "<b>Invalid image file path: %s.</b>\nPress <b>Select Image</b> to select an image." % image_path
            else:
                image_path = os.path.abspath(image_path)
                extend_name = os.path.splitext(image_path)[1][1:]
                if extend_name not in DEPLOYABLE_IMAGE_TYPES:
                    valid = False
                    lbl = "<b>Undeployable imge type: %s</b>\nPress <b>Select Image</b> to select an image." % extend_name

            if not valid:
                image_path = ''
                crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
                button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK)
                HobButton.style_button(button)
                crumbs_dialog.run()
                crumbs_dialog.destroy()

        self.deploy_dialog = DeployImageDialog(Title, image_path, self,
                                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
                                        | gtk.DIALOG_NO_SEPARATOR, None, standalone=True)
        close_button = self.deploy_dialog.add_button("Close", gtk.RESPONSE_NO)
        HobAltButton.style_button(close_button)
        close_button.connect('clicked', gtk.main_quit)

        write_button = self.deploy_dialog.add_button("Write USB image", gtk.RESPONSE_YES)
        HobAltButton.style_button(write_button)

        self.deploy_dialog.connect('select_image_clicked', self.select_image_clicked_cb)
        self.deploy_dialog.connect('destroy', gtk.main_quit)
        response = self.deploy_dialog.show()

    def select_image_clicked_cb(self, dialog):
        cwd = os.getcwd()
        dialog = ImageSelectionDialog(cwd, DEPLOYABLE_IMAGE_TYPES, Title, self, gtk.FILE_CHOOSER_ACTION_SAVE )
        button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
        HobAltButton.style_button(button)
        button = dialog.add_button("Open", gtk.RESPONSE_YES)
        HobAltButton.style_button(button)
        response = dialog.run()

        if response == gtk.RESPONSE_YES:
            if not dialog.image_names:
                lbl = "<b>No selections made</b>\nClicked the radio button to select a image."
                crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
                button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK)
                HobButton.style_button(button)
                crumbs_dialog.run()
                crumbs_dialog.destroy()
                dialog.destroy()
                return

            # get the full path of image
            image_path = os.path.join(dialog.image_folder, dialog.image_names[0])
            self.deploy_dialog.set_image_text_buffer(image_path)
            self.deploy_dialog.set_image_path(image_path)

        dialog.destroy()

def main():
    parser = optparse.OptionParser(
                usage = """%prog [-h] [image_file]

%prog writes bootable images to USB devices. You can
provide the image file on the command line or select it using the GUI.""")

    options, args = parser.parse_args(sys.argv)
    image_file = args[1] if len(args) > 1 else ''
    dw = DeployWindow(image_file)

if __name__ == '__main__':
    try:
        main()
        gtk.main()
    except Exception:
        import traceback
        traceback.print_exc()
