def test_get_available_audio_options_should_include_recomended_options(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 48000, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 48000, 'depth': '16 bit' }]
            }
        
        expected_in  = AudioSetting(48000,'16 bit', current = True)
        expected_in.set_recommended()
        expected_out = AudioSetting(48000,'16 bit', current = True)
        expected_out.set_recommended()
        

        expected = {
                    "inputs" : [expected_in], 
                    "outputs": [expected_out] 
                   }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.DEFAULT_CONFIG
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")
        
        actual = capi.get_available_audio_options()

        self.assertListContentsEqual(expected['inputs'],actual['inputs'])
        self.assertListContentsEqual(expected['outputs'],actual['outputs'])
    def test_get_available_audio_options_sets_currently_selected(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '16 bit' }]
            }

        mock_get_valid_sampling_options.return_value = audio_options
        config = self.DEFAULT_CONFIG.copy()
        config['input_bit_depth'] = '16 bit'
        config['input_sample_frequency'] = 44100
        config['output_bit_depth'] = '16 bit'
        config['output_sample_frequency'] = 44100

        mock_load.return_value = config

        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")

        actual = capi.get_available_audio_options()

        in1 = AudioSetting(44100,'16 bit', current = True)
        in2 = AudioSetting(48000,'16 bit', recommended = True)
        out1 = AudioSetting(44100,'16 bit', current = True)
        out2 = AudioSetting(48000,'16 bit', recommended = True)
        

        self.assertListContentsEqual([in1, in2],actual['inputs'])
        self.assertListContentsEqual([out1, out2],actual['outputs'])
    def test_get_available_audio_options_sets_currently_selected(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '16 bit' }]
            }

        mock_get_valid_sampling_options.return_value = audio_options
        config = self.default_config
        config.audio.input.bit_depth = '16 bit'
        config.audio.input.sample_rate = 44100
        config.audio.output.bit_depth = '16 bit'
        config.audio.output.sample_rate = 44100

        mock_load.return_value = config

        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")

        actual = capi.get_available_audio_options()

        in1 = AudioSetting(44100,'16 bit', current = True)
        in2 = AudioSetting(48000,'16 bit', recommended = True)
        out1 = AudioSetting(44100,'16 bit', current = True)
        out2 = AudioSetting(48000,'16 bit', recommended = True)
        

        self.assertListContentsEqual([in1, in2],actual['inputs'])
        self.assertListContentsEqual([out1, out2],actual['outputs'])
    def test_get_available_audio_options_should_include_recomended_options(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 48000, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 48000, 'depth': '16 bit' }]
            }
        
        expected_in  = AudioSetting(48000,'16 bit', current = True)
        expected_in.set_recommended()
        expected_out = AudioSetting(48000,'16 bit', current = True)
        expected_out.set_recommended()
        

        expected = {
                    "inputs" : [expected_in], 
                    "outputs": [expected_out] 
                   }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.default_config
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")
        
        actual = capi.get_available_audio_options()

        self.assertListContentsEqual(expected['inputs'],actual['inputs'])
        self.assertListContentsEqual(expected['outputs'],actual['outputs'])
    def test_get_available_audio_options_should_get_list_of_settings(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 22000, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 22000, 'depth': '32 bit Floating Point' }]
            }
        expected = {
                    "inputs" : [AudioSetting(22000,'16 bit')],
                    "outputs": [AudioSetting(22000,'32 bit Floating Point')]
                   }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.DEFAULT_CONFIG
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")
        
        actual = capi.get_available_audio_options()

        self.assertListContentsEqual(expected['inputs'],actual['inputs'])
        self.assertListContentsEqual(expected['outputs'],actual['outputs'])
    def test_get_available_audio_options_should_get_list_of_settings(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 22000, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 22000, 'depth': '32 bit Floating Point' }]
            }
        expected = {
                    "inputs" : [AudioSetting(22000,'16 bit')],
                    "outputs": [AudioSetting(22000,'32 bit Floating Point')]
                   }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.default_config
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")
        
        actual = capi.get_available_audio_options()

        self.assertListContentsEqual(expected['inputs'],actual['inputs'])
        self.assertListContentsEqual(expected['outputs'],actual['outputs'])
    def test_get_available_audio_options_is_sorted(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [], 
            "output": [{'sample_rate' : 48000, 'depth': '32 bit Floating Point' },{'sample_rate' : 44100, 'depth': '16 bit' },{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '24 bit' } ]
            }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.DEFAULT_CONFIG
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")

        actual = capi.get_available_audio_options()

        expected_ordered = [
            AudioSetting(44100, '16 bit'),
            AudioSetting(44100, '24 bit'),
            AudioSetting(48000, '16 bit', recommended = True, current = True),
            AudioSetting(48000, '32 bit Floating Point'),
        ] 
        self.assertListContentsEqual(expected_ordered,actual['outputs'])
    def test_get_available_audio_options_should_add_recommend_flag_to_one_option(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 48000, 'depth': '32 bit Floating Point' },{'sample_rate' : 44100, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '16 bit' } ]
            }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.DEFAULT_CONFIG
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")

        actual = capi.get_available_audio_options()

        expected_input = AudioSetting(44100,'16 bit', recommended = True)
        unexpected_input = AudioSetting(48000,'32 bit Floating Point')
        expected_output = AudioSetting(48000,'16 bit', recommended = True, current = True)
        unexpected_output = AudioSetting(44100,'16 bit')

        self.assertListContentsEqual([expected_input, unexpected_input],actual['inputs'])
        self.assertListContentsEqual([unexpected_output,expected_output],actual['outputs'])
    def test_get_available_audio_options_is_sorted(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [], 
            "output": [{'sample_rate' : 48000, 'depth': '32 bit Floating Point' },{'sample_rate' : 44100, 'depth': '16 bit' },{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '24 bit' } ]
            }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.default_config
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")

        actual = capi.get_available_audio_options()

        expected_ordered = [
            AudioSetting(44100, '16 bit'),
            AudioSetting(44100, '24 bit'),
            AudioSetting(48000, '16 bit', recommended = True, current = True),
            AudioSetting(48000, '32 bit Floating Point'),
        ] 
        self.assertListContentsEqual(expected_ordered,actual['outputs'])
    def test_get_available_audio_options_should_add_recommend_flag_to_one_option(self, mock_load, mock_get_valid_sampling_options):
        audio_options = { 
            "input" : [{'sample_rate' : 48000, 'depth': '32 bit Floating Point' },{'sample_rate' : 44100, 'depth': '16 bit' }], 
            "output": [{'sample_rate' : 48000, 'depth': '16 bit' },{'sample_rate' : 44100, 'depth': '16 bit' } ]
            }

        mock_get_valid_sampling_options.return_value = audio_options
        mock_load.return_value = self.default_config
        capi = ConfigurationAPI(ConfigurationManager())
        capi.load_printer("Printer")

        actual = capi.get_available_audio_options()

        expected_input = AudioSetting(44100,'16 bit', recommended = True)
        unexpected_input = AudioSetting(48000,'32 bit Floating Point')
        expected_output = AudioSetting(48000,'16 bit', recommended = True, current = True)
        unexpected_output = AudioSetting(44100,'16 bit')

        self.assertListContentsEqual([expected_input, unexpected_input],actual['inputs'])
        self.assertListContentsEqual([unexpected_output,expected_output],actual['outputs'])
class SetupAudioUI(PeachyFrame):

    def initialize(self):
        self.grid()
        self._current_printer = self.kwargs['printer']
        self._configuration_api = ConfigurationAPI(self._configuration_manager)
        self._configuration_api.load_printer(self._current_printer)

        audio_options = self._configuration_api.get_available_audio_options()

        self._input_options = dict([ (str(option), option) for option in audio_options['inputs']])
        self._output_options = dict([ (str(option), option) for option in audio_options['outputs']])

        if (len(self._input_options) < 1 or len(self._output_options) < 1):
            logging.error("No inputs available")
            tkMessageBox.showwarning('Error','Audio card appears to not be setup correctly, Have you plugged in your dripper and printer?')
            self._back()
            return
            
        self._input_audio_selection_current = StringVar()
        self._input_audio_selection_current.set(self._currently_selected(self._input_options))

        self._output_options = dict([ (str(option), option) for option in audio_options['outputs']])

        self._output_audio_selection_current = StringVar()
        self._output_audio_selection_current.set(self._currently_selected(self._output_options))
        
        Label(self, text = 'Printer: ').grid(column=0,row=10)
        Label(self, text = self._configuration_api.current_printer()).grid(column=1,row=10)
        Button(self, text='?', command=self._help).grid(column=2, row=10,stick=N+E)

        Label(self).grid(column=0,row=20)
        Label(self, text = 'Selecting a format not supported by your system may result in odd behaviour').grid(column=0,row=25,columnspan=3)
        Label(self).grid(column=0,row=26)

        Label(self, text = "Audio Input Settings" ).grid(column=0,row=30)
        OptionMenu( self, self._input_audio_selection_current, *self._input_options.keys()).grid(column=1,row=30,sticky=NSEW)

        Label(self, text = "Audio Output Settings" ).grid(column=0,row=40)
        OptionMenu(self, self._output_audio_selection_current, *self._output_options.keys()).grid(column=1,row=40,sticky=NSEW)

        Label(self).grid(column=0,row=50)

        Button(self, text ="Back", command = self._back).grid(column=0,row=60,sticky=N+S+W)
        Button(self, text ="Save", command = self._save).grid(column=1,row=60,sticky=N+S+E)

        self.update()

    def _currently_selected(self, audio_options):
        current_option = [ k for k, v in audio_options.iteritems() if v.current ]
        if (len(current_option) == 0):
            return audio_options[0]
        else:
            return current_option[0]

    def _get_recommend_audio_index(self, options):
        for i in range(0,len(options)):
            if options[i].endswith('(Recommended)'):
                return i
        return 0

    def _back(self):
        self.navigate(SetupUI)

    def _help(self):
        PopUp(self,'Help', help_text.setup_audio_help)

    def _save(self):
        input_option = self._input_options[self._input_audio_selection_current.get()]
        output_option = self._output_options[self._output_audio_selection_current.get()]
        
        self._configuration_api.set_audio_input_options(input_option)
        self._configuration_api.set_audio_output_options(output_option)

        self.navigate(SetupUI)

    def close(self):
        pass
class SetupAudioUI(PeachyFrame):
    def initialize(self):
        self.grid()
        self._current_printer = self.kwargs['printer']
        self._configuration_api = ConfigurationAPI(self._configuration_manager)
        self._configuration_api.load_printer(self._current_printer)

        audio_options = self._configuration_api.get_available_audio_options()

        self._input_options = dict([(str(option), option)
                                    for option in audio_options['inputs']])
        self._output_options = dict([(str(option), option)
                                     for option in audio_options['outputs']])

        if (len(self._input_options) < 1 or len(self._output_options) < 1):
            logging.error("No inputs available")
            tkMessageBox.showwarning(
                'Error',
                'Audio card appears to not be setup correctly, Have you plugged in your dripper and printer?'
            )
            self._back()
            return

        self._input_audio_selection_current = StringVar()
        self._input_audio_selection_current.set(
            self._currently_selected(self._input_options))

        self._output_options = dict([(str(option), option)
                                     for option in audio_options['outputs']])

        self._output_audio_selection_current = StringVar()
        self._output_audio_selection_current.set(
            self._currently_selected(self._output_options))

        Label(self, text='Printer: ').grid(column=0, row=10)
        Label(self,
              text=self._configuration_api.current_printer()).grid(column=1,
                                                                   row=10)
        Button(self, text='?', command=self._help).grid(column=2,
                                                        row=10,
                                                        stick=N + E)

        Label(self).grid(column=0, row=20)
        Label(
            self,
            text=
            'Selecting a format not supported by your system may result in odd behaviour'
        ).grid(column=0, row=25, columnspan=3)
        Label(self).grid(column=0, row=26)

        Label(self, text="Audio Input Settings").grid(column=0, row=30)
        OptionMenu(self, self._input_audio_selection_current,
                   *self._input_options.keys()).grid(column=1,
                                                     row=30,
                                                     sticky=NSEW)

        Label(self, text="Audio Output Settings").grid(column=0, row=40)
        OptionMenu(self, self._output_audio_selection_current,
                   *self._output_options.keys()).grid(column=1,
                                                      row=40,
                                                      sticky=NSEW)

        Label(self).grid(column=0, row=50)

        Button(self, text="Back", command=self._back).grid(column=0,
                                                           row=60,
                                                           sticky=N + S + W)
        Button(self, text="Save", command=self._save).grid(column=1,
                                                           row=60,
                                                           sticky=N + S + E)

        self.update()

    def _currently_selected(self, audio_options):
        current_option = [k for k, v in audio_options.iteritems() if v.current]
        if (len(current_option) == 0):
            return audio_options[0]
        else:
            return current_option[0]

    def _get_recommend_audio_index(self, options):
        for i in range(0, len(options)):
            if options[i].endswith('(Recommended)'):
                return i
        return 0

    def _back(self):
        self.navigate(SetupUI)

    def _help(self):
        PopUp(self, 'Help', help_text.setup_audio_help)

    def _save(self):
        input_option = self._input_options[
            self._input_audio_selection_current.get()]
        output_option = self._output_options[
            self._output_audio_selection_current.get()]

        self._configuration_api.set_audio_input_options(input_option)
        self._configuration_api.set_audio_output_options(output_option)

        self.navigate(SetupUI)

    def close(self):
        pass