def _recapture_image_prompt(original_path, message):
    global _myEvent
    badKey = False
    na_path = os.path.join(_sitePackages, "image_not_captured_yet.png")
    temp_path = na_path
    three_buttons = ["Instant Capture", "User-Initiated Capture (CTRL+SHIFT+2)", "Show Capture", "Show Original", ]
    four_buttons = ["Instant Capture", "User-Initiated Capture (CTRL+SHIFT+2)", "Show Capture", "Show Original", "Move On"]
    icon = ImageIcon(original_path)
    while True:
        if temp_path == na_path:
            buttons = three_buttons
        else:
            buttons = four_buttons
        choice = JOptionPane().showOptionDialog(None, message , "Capture new image or close this window to retry the code.",  JOptionPane.PLAIN_MESSAGE, 0, icon, buttons, buttons[0])
        if choice == -1:
            #print "Image updater closed without doing anything."
            break #with this included the while loop will quit and the _screen_logger loop will retry the original image
        elif choice == 0:
            temp_path = sikuli.capture()
            if temp_path == None:
                temp_path = na_path
                icon = ImageIcon(original_path)
            else:
                icon = ImageIcon(temp_path)
        elif choice == 1:
            if not sikuli.Env.addHotkey("2", sikuli.KeyModifier.SHIFT + sikuli.KeyModifier.CTRL, _capture_wait):
                badKey = True
                sikuli.Env.addHotkey(Key.F2, sikuli.KeyModifier.SHIFT + sikuli.KeyModifier.CTRL, _capture_wait)
            _myEvent.clear()
            _myEvent.wait()
            temp_path = sikuli.SCREEN.capture()
            if temp_path == None:
                temp_path = na_path
                icon = ImageIcon(original_path)
            else:
                icon = ImageIcon(temp_path)
            if badKey:
                sikuli.Env.removeHotkey(Key.F2, sikuli.KeyModifier.SHIFT + sikuli.KeyModifier.CTRL)
            else:
                sikuli.Env.removeHotkey("2", sikuli.KeyModifier.SHIFT + sikuli.KeyModifier.CTRL)
        elif choice == 2:
            icon = ImageIcon(temp_path)
        elif choice == 3:
            icon = ImageIcon(original_path)
        elif choice == 4:
            shutil.copyfile(temp_path, original_path)
            break
        else:
            #print "You added an extra button and it doesn't do anything."
            break
    def _screen_logger_wrapper(*args, **kwargs):
        #print "Arguments were: %s %s | %s" % (func.__name__, args, kwargs)
        frames = inspect.getouterframes(inspect.currentframe())
        scriptname = os.path.basename(frames[1][1])[:-3]
        count = 0

        for frame in frames:
            if frame[3] == '_screen_logger_wrapper':
                count = count +1

        # Sikuli uses find and wait internally, so the only versions of the
        # sikuli commands that should be decorated are those that are at the
        # highest level (i.e. those that are only wrapped once).
        if count == 1:
            fname = func.__name__
            #frame = frames[1][0]
            #filename = frames[1][1]
            lineno = frames[1][2]
            #function = frames[1][3]
            code_context = frames[1][4][0]
            #index = frames[1][5]
            output = "[Line "+str(lineno)+"] "+str(code_context).rstrip()
            number_of_screens = sikuli.getNumberScreens()
            if isinstance(args[0],SikuliRegion):
                specific_area = True
                area = args[0]
                image = args[1]
                if fname == "wait" and _imageUpdating:
                    targs = list(args)
                    if len(args)==1:
                        targs.append(0)
                    elif len(args)>1:
                        targs[2] = 0
                        args = targs

                elif fname == "dragDrop":
                    extraImage = args[2]
            else:
                specific_area = False
                area = sikuli.SCREEN
                image = args[0]
                if fname == "wait" and _imageUpdating:
                    targs = list(args)
                    if len(args)==1:
                        targs.append(0)
                    elif len(args)>1:
                        targs[1] = 0
                        args = targs
                elif fname == "dragDrop":
                    extraImage = args[1]

            if fname == "dragDrop":
                display_order = "[start]"
            else:
                display_order = ""

            if isinstance(image, float) or isinstance(image, int):
                _textLog = True
            elif isinstance(image, sikuli.Pattern):
                _textLog = False
                imageName = os.path.basename(image.getFilename())
            else:
                _textLog = False
                imageName = image
            if fname == "dragDrop":
                if isinstance(extraImage, sikuli.Pattern):
                    extraImageName = os.path.basename(extraImage.getFilename())
                else:
                    extraImageName = extraImage

            ### TODO replace image in code_context with image for HTML log, consolidate columns
            while True:
                try:
                    screenshot = sikuli.capture(area)
                    if specific_area or fname == "type" or fname == "paste" or fname == "onChange" or fname == "observe" or _textLog:
                        result = func(*args, **kwargs)
                    else:
                        failures = 0
                        for screen_id in range(number_of_screens):
                            try:
                                my_screen = sikuli.Screen(screen_id)
                                screen_check_func = getattr(my_screen,func.__name__)
                                result = screen_check_func(*args, **kwargs)
                                break
                            except sikuli.FindFailed:
                                failures = failures +1
                            except:
                                #print "base exception"
                                raise
                        if failures == number_of_screens:
                            #print "both screens FindFailed"
                            raise sikuli.FindFailed("Find Failed on both Screens")
                    if fname =="exists" and result == None and _imageUpdating:
                        raise sikuli.FindFailed("Exists() did not find anything.")
                    if _logType == "SUCCESS" or _logType == "ALL":
                        if _textLog:
                            similarity ="N/A"
                        else:
                            similarity = str(simpleCompare(screenshot, image, 4))
                        _write_error("+++",scriptname, output+display_order+"[S:"+similarity+"]")
                        _write_html_row(scriptname,func.__name__+display_order, image, "Success", screenshot, similarity)
                    #if _imageUpdating:
                    #    if fname == "type" or fname == "paste" or fname == "onChange" or fname == "observe" or fname == "onVanish" or fname == "onAppear":
                    #        pass
                    #    elif specific_area:
                    #        specific_area.getLastMatch().highlight(1)
                    #    else:
                    #        my_screen.getLastMatch().highlight(1)
                    return result
                except sikuli.FindFailed:
                    if _textLog:
                        similarity ="N/A"
                    else:
                        screenshot = area.getLastScreenImageFile(tempfile.gettempdir(), str(int(time.time()*1000)))
                    similarity = str(simpleCompare(screenshot, image, 4))
                    error_text = traceback.format_exc()
                    if fname == "dragDrop" and extraImageName in error_text:
                        if _logType == "SUCCESS" or _logType == "ALL":
                            _write_error("+++",scriptname, output+display_order+"[S:"+similarity+"]")
                            _write_html_row(scriptname,func.__name__+display_order, image, "Success", screenshot, similarity)
                        display_order = "[end]"
                        image = extraImage
                        similarity = str(simpleCompare(screenshot, image, 4))
                    if _imageUpdating:
                        line_data = "\n"+frames[1][1]+"\nCurrent Similarity is: "+str(similarity)+"\n"+output+display_order
                        if specific_area:
                            area.highlight(1)
                        _recapture_image_prompt(_find_valid_image(image), line_data)
                        continue
                    else:
                        if _logType == "FAIL" or _logType == "ALL":
                            _write_error("---",scriptname, output+display_order+"[S:"+similarity+"]")
                            _write_html_row(scriptname,func.__name__+display_order, image, "Fail", screenshot, similarity)
                        raise
                except:
                    raise
        else:
            return func(*args, **kwargs)
def _write_html_row(script_name, action_type, expected, result_type, screenshot, similarity):
    doc, tag, text = Doc().tagtext()
    # Create the row
    # Status, Time and Date, Test name, Action, Expected, Screenshot, Similarity
    with tag("tr"):
        if result_type == "Success":
            with tag("td", ('bgcolor', 'green')):
                text("+++")
        elif result_type == "Fail":
            with tag("td", ('bgcolor', 'red')):
                text("---")
        else:
            with tag("td"):
                text("???")
        with tag("td"):
            text(time.strftime("%H:%M:%S %x"))
        with tag("td"):
            text(script_name)
        with tag("td"):
            text(action_type)
        with tag("td"):
            # If 'expected' is given, figure out what kind
            # of thing it is
            if expected:
                expected_path = ""
                # If it's a pattern, get the image
                if isinstance(expected, sikuli.Pattern):
                    full_path = _find_valid_image(expected.getFilename())
                    expected_path = _copy_testfile(full_path)
                # If it's a match or a region, take a
                # screenshot of the area
                elif (isinstance(expected, sikuli.Match) or
                      isinstance(expected, sikuli.Region)):
                    screencap = sikuli.capture(expected)
                    expected_path = _copy_testfile(screencap)
                elif isinstance(expected, sikuli.Location):
                    # Create an area 50px around the location
                    r = sikuli.Region(expected.getX(), expected.getY(), 0, 0)
                    r = r.nearby()
                    # take a screenshot
                    screencap = sikuli.capture(r)
                    expected_path = _copy_testfile(screencap)
                elif isinstance(expected, str):
                    full_path = _find_valid_image(expected)

                    # If a path was found, add a clickable image.
                    # If not, add text.
                    if full_path:
                        expected_path = _copy_testfile(full_path)

                if expected_path == "":
                    text(str(expected))
                else:
                    with tag("a", href="./log/"+expected_path):
                        doc.stag("img", src="./log/"+expected_path)

        with tag("td"):
            screenshot_path = _copy_testfile(screenshot)
            with tag("a", href="./log/"+screenshot_path):
                doc.stag("img", src="./log/"+screenshot_path)
        with tag("td"):
            text(similarity)

    # Write the row to the partial html file
    with open(_partialHTML, "a") as f:
        f.write(doc.getvalue())