import numpy as np

import matplotlib.gridspec as gridspec
from matplotlib import pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure

import iota.components.iota_misc as misc
import iota.components.iota_controls as ct
from iota.components.iota_utils import InputFinder

import prime.postrefine.mod_gui_dialogs as dlg
import prime.postrefine.mod_threads as thr
from prime.postrefine.mod_input import master_phil

ginp = InputFinder()

# Platform-specific stuff
# TODO: Will need to test this on Windows at some point
if wx.Platform == '__WXGTK__':
    norm_font_size = 10
    button_font_size = 12
    LABEL_SIZE = 14
    CAPTION_SIZE = 12
    python = 'python'
elif wx.Platform == '__WXMAC__':
    norm_font_size = 12
    button_font_size = 14
    LABEL_SIZE = 14
    CAPTION_SIZE = 12
    python = "Python"
    def initialize_interface(self):
        """ Initialize properties specific for command line

    :return: True if successful, False if fails
    """
        self.args, self.phil_args = parse_command_args(
            self.iver, self.help_message).parse_known_args()
        ginp = InputFinder()

        # Check for type of input
        if not self.args.path:  # No input
            parse_command_args(self.iver, self.help_message).print_help()
            if self.args.default:  # Write out default params and exit
                help_out, txt_out = inp.print_params()
                print('\n{:-^70}\n'.format('IOTA Parameters'))
                print(help_out)
            return False, 'IOTA_XTERM_INIT: OUTPUT PARAMETERS ONLY'
        elif len(self.args.path) > 1:  # If multiple paths / wildcards
            file_list = ginp.make_input_list(self.args.path)
            list_file = os.path.join(os.path.abspath(os.path.curdir),
                                     'input.lst')
            with open(list_file, 'w') as lf:
                lf.write('\n'.join(file_list))
            msg = "\nIOTA will run in AUTO mode using wildcard datapath:\n" \
                  "{} files found, compiled in {}\n".format(len(file_list), list_file)
            self.iota_phil = inp.process_input(self.args, self.phil_args,
                                               list_file, 'auto', self.now)
            self.params = self.iota_phil.extract()

        else:  # If single path, check type
            carg = os.path.abspath(self.args.path[0])
            if os.path.isfile(carg):
                ptype = ginp.get_file_type(carg)
                if ptype.lower() in ('raw image', 'image pickle'):
                    msg = "\nIOTA will run in SINGLE-FILE mode using {}:\n".format(
                        carg)
                    mode = 'auto'
                elif ('iota' and 'settings' in ptype.lower()):
                    msg = '\nIOTA will run in SCRIPT mode using {}:\n'.format(
                        carg)
                    mode = 'file'
                elif 'list' in ptype.lower():
                    msg = "\nIOTA will run in AUTO mode using {}:\n".format(
                        carg)
                    mode = 'auto'
                else:
                    pr = 'WARNING! File format not recognized. Proceed anyway? [Y/N] '
                    unknown_file = raw_input(pr)
                    if 'y' in unknown_file.lower():
                        ftype = raw_input(
                            "File type? [image, list, or parameters] ")
                        msg = "\nIOTA will run WITH DODGY input using {}:\n".format(
                            carg)
                        if 'par' in ftype:
                            mode = 'file'
                        else:
                            mode = 'auto'
                    else:
                        print('Exiting...')
                        return False, 'IOTA_XTERM_INIT_ERROR: Unrecognizable input!'
            elif os.path.isdir(carg):
                ptype = ginp.get_folder_type(carg)
                if ('image' and 'folder' in ptype.lower()):
                    msg = "\nIOTA will run in AUTO mode using {}:\n".format(
                        carg)
                    mode = 'auto'
                else:
                    msg = "IOTA_XTERM_INIT_ERROR: No images in {}!".format(
                        carg)
                    print(self.logo)
                    print(msg)
                    return False, msg

            # If user provided gibberish
            else:
                msg = "IOTA_XTERM_INIT_ERROR: Invalid input! Need parameter filename " \
                      "or data folder."
                print(self.logo)
                print(msg)
                return False, msg

            # Initialize parameters for this command-line run
            self.iota_phil = inp.process_input(self.args, self.phil_args, carg,
                                               mode, self.now)
            self.params = self.iota_phil.extract()

        # Identify indexing / integration program and add to logo
        b_end = " with {}".format(
            str(self.params.advanced.processing_backend).upper())
        prg = "{:>{w}}".format(b_end, w=76)
        self.logo += prg
        print(self.logo)
        print('\n{}\n'.format(self.now))
        if msg != '':
            print(msg)

        if self.args.analyze is not None:
            print('ANALYSIS ONLY will be performed (analyzing run #{})'.format(
                self.args.analyze))
            self.analyze_prior_results('{:003d}'.format(int(
                self.args.analyze)))
            return False

        if self.params.mp.method == 'mpi':
            rank, size = get_mpi_rank_and_size()
            self.master_process = rank == 0
        else:
            self.master_process = True

        # Call function to read input folder structure (or input file) and
        # generate list of image file paths
        if self.params.cctbx_ha14.selection.select_only.flag_on:
            cmd.Command.start("Importing saved grid search results")
            self.gs_img_objects = self.make_int_object_list()
            self.input_list = [i.conv_img for i in self.gs_img_objects]
            cmd.Command.end("Importing saved grid search results -- DONE")
        else:
            cmd.Command.start("Reading input files")
            self.input_list = self.make_input_list()
            cmd.Command.end("Reading input files -- DONE")

        # Select range of images/objects if turned on
        if self.params.advanced.image_range.flag_on:
            self.input_list = self.select_image_range(self.input_list)

        # Pick a randomized subset of images/objects if turned on
        if self.params.advanced.random_sample.flag_on and \
                self.params.advanced.random_sample.number < len(self.input_list):
            cmd.Command.start("Selecting {} random images out of {} found"
                              "".format(
                                  self.params.advanced.random_sample.number,
                                  len(self.input_list)))
            self.input_list = self.select_random_subset(self.input_list)
            cmd.Command.end(
                "Selecting {} random images out of {} found -- DONE"
                "".format(self.params.advanced.random_sample.number,
                          len(self.input_list)))

            # Check for -l option, output list of input files and exit
        if self.args.list:
            list_file = os.path.abspath("{}/input.lst".format(os.curdir))

            # Check if other files of this name exist under the current folder
            list_folder = os.path.dirname(list_file)
            list_files = [
                i for i in os.listdir(list_folder) if i.endswith(".lst")
            ]
            if len(list_files) > 0:
                list_file = os.path.join(
                    list_folder, "input_{}.lst".format(len(list_files)))

            msg = 'IOTA_XTERM_INIT: INPUT LIST ONLY option selected'
            print('\n{}'.format(msg))
            print('Input list in {} \n\n'.format(list_file))
            with open(list_file, "w") as lf:
                for i, input_file in enumerate(self.input_list, 1):
                    lf.write('{}\n'.format(input_file))
                    print("{}: {}".format(i, input_file))
                    lf.write('{}\n'.format(input_file))
            print('\nExiting...\n\n')
            return False, msg

        return True, 'IOTA_XTERM_INIT: Initialization complete!'