class PostProcessingDatabase(object):
    __shared_state = {}

    def __init__(self):
        self.__dict__ = self.__shared_state

    def refresh(self):
        self.real_time_database = RealTimeDatabase()
        self._initialize_data_arrays()

    def _initialize_data_arrays(self):
        self.rpms, self.torques = self._create_sorted_rpms_and_torques()
        self.powers = self._calculate_powers()

    #TODO Not efficient...
    def _create_sorted_rpms_and_torques(self):
        #Pour prendre seulement les points ou la vitesse augmente.
        self.max_index = self._find_end_of_data_acquisition_index(self.real_time_database)

        velocities = self.real_time_database.get_velocities()[:self.max_index]
        rpms = self._convert_velocities_to_rpms(velocities)[:self.max_index]
        torques = self.real_time_database.get_torques()[:self.max_index]

        sorted_index_array = self._calculate_sorted_index_array(rpms)
        sorted_rpms = rpms[sorted_index_array]
        sorted_torques = torques[sorted_index_array]

        return sorted_rpms, sorted_torques

    def _find_end_of_data_acquisition_index(self, real_time_database):
        return np.argmax(real_time_database.get_velocities())

    def _calculate_sorted_index_array(self, rpms):
        return np.argsort(rpms)

    def _convert_velocities_to_rpms(self, velocities):
        return velocities * 60 / (2 * pi)

    def _calculate_powers(self):
        return self.real_time_database.get_velocities()[:self.max_index] * self.torques

    def serialize_data_as_csv(self):
        data_string = ""
        data_string += "Rpms, Torques, Powers \n"

        for i in range(len(self.rpms)):
            data_string += (str(self.rpms[i]) + ",")
            data_string += (str(self.torques[i]) + ",")
            data_string += (str(self.powers[i]) + "\n")

        return data_string

    def get_rpms(self):
        return self.rpms

    def get_torques(self):
        return self.torques

    def get_powers(self):
        return self.powers
    def _initializeApp(self):
        self.database = RealTimeDatabase()
        self.database.initialize_database()
        self.post_processing_database = PostProcessingDatabase()
        self.dropbox_database = DropboxDatabase()
        self.dropbox_database.initialize_database()
        self.properties_parser = PropertiesParser()

        self.real_time_subplots = self._init_real_time_subplots()
        self.post_treatment_subplots = self._init_post_processing_subplots()

        self._init_encoder_controller()
        self.top_frame_controller = TopFrameController(self.real_time_subplots, self.post_treatment_subplots, self)

        return True
 def refresh(self):
     self.real_time_database = RealTimeDatabase()
     self._initialize_data_arrays()
class AppController(object):
    def __init__(self):
        self._initializeApp()
        self.REAL_TIME_FILENAME = "RealTime.csv"
        self.POST_PROCESSING_FILENAME = "PostProcessing.csv"
        self.INJECTION_TABLE_FILENAME = "InjectionTable.csv"

    def reset_app(self):
        self.top_frame_controller.close_frame()
        self._initializeApp()

    def _initializeApp(self):
        self.database = RealTimeDatabase()
        self.database.initialize_database()
        self.post_processing_database = PostProcessingDatabase()
        self.dropbox_database = DropboxDatabase()
        self.dropbox_database.initialize_database()
        self.properties_parser = PropertiesParser()

        self.real_time_subplots = self._init_real_time_subplots()
        self.post_treatment_subplots = self._init_post_processing_subplots()

        self._init_encoder_controller()
        self.top_frame_controller = TopFrameController(self.real_time_subplots, self.post_treatment_subplots, self)

        return True

    def _init_encoder_controller(self):
        self.encoder_controller = EncoderController(self.database)

    def _init_real_time_subplots(self):
        plots_to_display = self.properties_parser.get_property("Real-Time Plots")

        if isinstance(plots_to_display, str):
            plots_to_display = real_time_plot_types

        factory = RealTimeSubplotFactory()
        return factory.create_subplots(plots_to_display)

    def _init_post_processing_subplots(self):
        plots_to_display = self.properties_parser.get_property("Post-Processing Plots")

        if plots_to_display is "":
            plots_to_display = post_processing_plot_types

        factory = PostProcessingSubplotFactory()
        return factory.create_subplots(plots_to_display)

    def start_data_acquisition(self):
        self.encoder_controller.start_data_acquisition()

    def stop_data_acquisition(self, save):
        self.encoder_controller.stop_data_acquisition()
        if save:
            self.save_data_to_dropbox()
        self.top_frame_controller.create_post_processing_panel()

    def save_data_to_dropbox(self):
        directory_name = (str(datetime.now().replace(microsecond=0)))

        self.post_processing_database.refresh()
        post_processing_data_string = self.post_processing_database.serialize_data_as_csv()
        real_time_data_string = self.database.serialize_data_as_csv()
        injection_table_string = InjectionTable().write_as_csv_string()

        saver = DropboxSaver()
        saver.save_data_to_dropbox(directory_name, self.REAL_TIME_FILENAME, real_time_data_string)
        saver.save_data_to_dropbox(directory_name, self.POST_PROCESSING_FILENAME, post_processing_data_string)
        saver.save_data_to_dropbox(directory_name, self.INJECTION_TABLE_FILENAME, injection_table_string)