import sys
import os

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import QtCore
from PyQt5.QtCore import *


class Grid_tab(QWidget):
    def __init__(self):
        super().__init__()

        self.columns_val = 8
        self.rows_val = 8
        self.col_dist_val = 50
        self.row_dist_val = 50
        self.channel_offset_val = 0
        self.elec_type_val = 'plain'
        self.ref_elec_type_val = 'plain'
        self.ref_elec_posx_val = 0.00
        self.ref_elec_posy_val = 0.00
        self.water_depth_val = 0.25

        self.gridlayout = QGridLayout()
        self.gridlayout.setColumnStretch(0, 5)
        self.gridlayout.setColumnStretch(1, 2)
        self.gridlayout.setColumnStretch(2, 1)

        # self.get_widgets()

        self.setLayout(self.gridlayout)

    def get_widgets(self):
        col_elecsU =QLabel('n', self)
        col_elecsL =QLabel('Electrod Columns:', self)
        self.col_elecs = QLineEdit(str(self.columns_val), self)
        self.gridlayout.addWidget(col_elecsL, 0, 0)
        self.gridlayout.addWidget(self.col_elecs, 0, 1)
        self.gridlayout.addWidget(col_elecsU, 0, 2)

        row_elecsU = QLabel('n', self)
        row_elecsL = QLabel('Electrod Rows:', self)
        self.row_elecs = QLineEdit(str(self.rows_val), self)
        self.gridlayout.addWidget(row_elecsL, 1, 0)
        self.gridlayout.addWidget(self.row_elecs, 1, 1)
        self.gridlayout.addWidget(row_elecsU, 1, 2)

        col_spaceU = QLabel('cm', self)
        col_spaceL = QLabel('Column spacing:', self)
        self.col_space = QLineEdit(str(self.col_dist_val), self)
        self.gridlayout.addWidget(col_spaceL, 2, 0)
        self.gridlayout.addWidget(self.col_space, 2, 1)
        self.gridlayout.addWidget(col_spaceU, 2, 2)

        row_spaceU = QLabel('cm', self)
        row_spaceL = QLabel('Row spacing:', self)
        self.row_space = QLineEdit(str(self.row_dist_val), self)
        self.gridlayout.addWidget(row_spaceL, 3, 0)
        self.gridlayout.addWidget(self.row_space, 3, 1)
        self.gridlayout.addWidget(row_spaceU, 3, 2)

        channel_offsetU = QLabel('n', self)
        channel_offsetL = QLabel('Channel offset:', self)
        self.channel_offset = QLineEdit(str(self.channel_offset_val), self)
        self.gridlayout.addWidget(channel_offsetL, 4, 0)
        self.gridlayout.addWidget(self.channel_offset, 4, 1)
        self.gridlayout.addWidget(channel_offsetU, 4, 2)

        elec_typeL = QLabel('Electrode Type:', self)
        self.elec_type = QLineEdit(self.elec_type_val, self)
        self.gridlayout.addWidget(elec_typeL, 5, 0)
        self.gridlayout.addWidget(self.elec_type, 5, 1)

        ref_elec_typeL = QLabel('Ref. Electrode Type:', self)
        self.ref_elec_type = QLineEdit(self.ref_elec_type_val, self)
        self.gridlayout.addWidget(ref_elec_typeL, 6, 0)
        self.gridlayout.addWidget(self.ref_elec_type, 6, 1)

        ref_elec_xU = QLabel('m', self)
        ref_elec_xL = QLabel('Ref. Electrode Pos-x:', self)
        self.ref_elec_x = QLineEdit('%.2f' % self.ref_elec_posx_val, self)
        self.gridlayout.addWidget(ref_elec_xL, 7, 0)
        self.gridlayout.addWidget(self.ref_elec_x, 7, 1)
        self.gridlayout.addWidget(ref_elec_xU, 7, 2)

        ref_elec_yU = QLabel('m', self)
        ref_elec_yL = QLabel('Ref. Electrode Pos-y:', self)
        self.ref_elec_y = QLineEdit('%.2f' % self.ref_elec_posy_val, self)
        self.gridlayout.addWidget(ref_elec_yL, 8, 0)
        self.gridlayout.addWidget(self.ref_elec_y, 8, 1)
        self.gridlayout.addWidget(ref_elec_yU, 8, 2)

        water_depthU = QLabel('cm', self)
        water_depthL = QLabel('Water depth:', self)
        self.water_depth = QLineEdit('%.2f' % self.water_depth_val, self)
        self.gridlayout.addWidget(water_depthL, 9, 0)
        self.gridlayout.addWidget(self.water_depth, 9, 1)
        self.gridlayout.addWidget(water_depthU, 9, 2)

        space = QLabel('', self)
        self.gridlayout.addWidget(space, 10, 0)

class Hardware_settings_tab(QWidget):
    def __init__(self):
        super().__init__()

        self.ai_sr_val = 20
        self.ai_max_vol_val = 1
        self.amp_name_val = "16-channel-amplifier"
        self.amp_model_val = 'EM-64B'
        self.amp_type_val = 'differential'
        self.gain_val = 100
        self.highpass_cutoff_val = 100
        self.lowpass_cutoff_val = 10

        self.gridlayout = QGridLayout()
        self.gridlayout.setColumnStretch(0, 5)
        self.gridlayout.setColumnStretch(1, 5)
        self.gridlayout.setColumnStretch(2, 1)

        # self.get_widgets()

        self.setLayout(self.gridlayout)

    def get_widgets(self):
        # hw_settingsL = QLabel('Hardware Settings:', self)
        # self.gridlayout.addWidget(hw_settingsL, 0, 0)

        AIsrU = QLabel('kHz', self)
        AIsrL = QLabel('AI Sample Rate:', self)
        self.AIsr = QLineEdit('%.3f' % self.ai_sr_val, self)
        self.gridlayout.addWidget(AIsrL, 1, 0)
        self.gridlayout.addWidget(self.AIsr, 1, 1)
        self.gridlayout.addWidget(AIsrU, 1, 2)

        AImaxVU = QLabel('mV', self)
        AImaxVL = QLabel('AI Max V:', self)
        self.AImaxV = QLineEdit('%.1f' % self.ai_max_vol_val, self)
        self.gridlayout.addWidget(AImaxVL, 2, 0)
        self.gridlayout.addWidget(self.AImaxV, 2, 1)
        self.gridlayout.addWidget(AImaxVU, 2, 2)

        AmplNameL = QLabel('Ampl. Name:', self)
        self.AmplName = QLineEdit(self.amp_name_val, self)
        self.gridlayout.addWidget(AmplNameL, 3, 0)
        self.gridlayout.addWidget(self.AmplName, 3, 1)

        AmplModelL = QLabel('Ampl. Model:', self)
        self.AmplModel = QLineEdit(self.amp_model_val, self)
        self.gridlayout.addWidget(AmplModelL, 4, 0)
        self.gridlayout.addWidget(self.AmplModel, 4, 1)

        AmplTypeL = QLabel('Ampl. Type:', self)
        self.AmplType = QLineEdit(self.amp_type_val, self)
        self.gridlayout.addWidget(AmplTypeL, 5, 0)
        self.gridlayout.addWidget(self.AmplType, 5, 1)

        gainL = QLabel('Gain:', self)
        self.gain = QLineEdit(str(self.gain_val), self)
        self.gridlayout.addWidget(gainL, 6, 0)
        self.gridlayout.addWidget(self.gain, 6, 1)

        hp_cutoffU = QLabel('Hz', self)
        hp_cutoffL = QLabel('Highpass cutoff:', self)
        self.hp_cutoff = QLineEdit(str(self.highpass_cutoff_val), self)
        self.gridlayout.addWidget(hp_cutoffL, 7, 0)
        self.gridlayout.addWidget(self.hp_cutoff, 7, 1)
        self.gridlayout.addWidget(hp_cutoffU, 7, 2)

        lp_cutoffU = QLabel('kHz', self)
        lp_cutoffL = QLabel('Lowpass cutoff:', self)
        self.lp_cutoff = QLineEdit('%.3f' % self.lowpass_cutoff_val, self)
        self.gridlayout.addWidget(lp_cutoffL, 8, 0)
        self.gridlayout.addWidget(self.lp_cutoff, 8, 1)
        self.gridlayout.addWidget(lp_cutoffU, 8, 2)

        space = QLabel('', self)
        self.gridlayout.addWidget(space, 9, 0)

class Recording_settings(QWidget):
    def __init__(self):
        super().__init__()

        self.experiment_name_val = 'recording fish behavior'
        self.startdate_val = '~'
        self.starttime_val = '~'
        self.location_val = 'Colombia - Los Llanos'
        self.position_val = '~N, ~W'
        self.water_temp_val = 20
        self.water_cond_val = 5
        self.water_ph_val = 7
        self.water_oxy_val = 0
        self.comment_val = '~'
        self.experimenter_val = 'T. Raab et al. :)'
        self.datatime_val = 100
        self.datainterval_val = 1000
        self.buffertime_val = 60

        self.gridlayout = QGridLayout()
        self.gridlayout.setColumnStretch(0, 5)
        self.gridlayout.setColumnStretch(1, 5)
        self.gridlayout.setColumnStretch(2, 1)

        # self.get_widgets()

        self.setLayout(self.gridlayout)

    def get_widgets(self):

        exp_nameL = QLabel('Experiment Name:', self)
        self.exp_name = QLineEdit(self.experiment_name_val, self)
        self.gridlayout.addWidget(exp_nameL, 0, 0)
        self.gridlayout.addWidget(self.exp_name, 0, 1)

        start_dateL = QLabel('Start Date:', self)
        self.start_date = QLineEdit(self.startdate_val, self)
        self.gridlayout.addWidget(start_dateL, 1, 0)
        self.gridlayout.addWidget(self.start_date, 1, 1)

        start_timeL = QLabel('Start Time:', self)
        self.start_time = QLineEdit(self.starttime_val, self)
        self.gridlayout.addWidget(start_timeL, 2, 0)
        self.gridlayout.addWidget(self.start_time, 2, 1)

        locationL = QLabel('Location:', self)
        self.location = QLineEdit(self.location_val, self)
        self.gridlayout.addWidget(locationL, 3, 0)
        self.gridlayout.addWidget(self.location, 3, 1)

        positionL = QLabel('Position:', self)
        self.position = QLineEdit(self.position_val, self)
        self.gridlayout.addWidget(positionL, 4, 0)
        self.gridlayout.addWidget(self.position, 4, 1)

        waterTempU = QLabel('C', self)
        waterTempL = QLabel('Water Temp:', self)
        self.waterTemp = QLineEdit('%.1f' % self.water_temp_val, self)
        self.gridlayout.addWidget(waterTempL, 5, 0)
        self.gridlayout.addWidget(self.waterTemp, 5, 1)
        self.gridlayout.addWidget(waterTempU, 5, 2)

        waterCondU = QLabel('uS/cm', self)
        waterCondL = QLabel('Water cond.:', self)
        self.waterCond = QLineEdit('%.1f' % self.water_cond_val, self)
        self.gridlayout.addWidget(waterCondL, 6, 0)
        self.gridlayout.addWidget(self.waterCond, 6, 1)
        self.gridlayout.addWidget(waterCondU, 6, 2)

        waterpHU = QLabel('pH')
        waterpHL = QLabel('Water-pH:')
        self.waterpH = QLineEdit('%.1f' % self.water_ph_val, self)
        self.gridlayout.addWidget(waterpHL, 7, 0)
        self.gridlayout.addWidget(self.waterpH, 7, 1)
        self.gridlayout.addWidget(waterpHU, 7, 2)

        waterOxyU = QLabel('mg/l', self)
        waterOxyL = QLabel('Water Oxygen:', self)
        self.waterOxy = QLineEdit('%.1f' % self.water_oxy_val, self)
        self.gridlayout.addWidget(waterOxyL, 8, 0)
        self.gridlayout.addWidget(self.waterOxy, 8, 1)
        self.gridlayout.addWidget(waterOxyU, 8, 2)

        commentL = QLabel('Comment:', self)
        self.comment = QLineEdit(self.comment_val, self)
        self.gridlayout.addWidget(commentL, 9, 0)
        self.gridlayout.addWidget(self.comment, 9, 1)

        experimenterL = QLabel('Experimenter:', self)
        self.experimenter = QLineEdit(self.experimenter_val, self)
        self.gridlayout.addWidget(experimenterL, 10, 0)
        self.gridlayout.addWidget(self.experimenter, 10, 1)

        DataTimeU = QLabel('ms', self)
        DataTimeL = QLabel('Data Time:', self)
        self.datatime = QLineEdit(str(self.datatime_val), self)
        self.gridlayout.addWidget(DataTimeL, 11, 0)
        self.gridlayout.addWidget(self.datatime, 11, 1)
        self.gridlayout.addWidget(DataTimeU, 11, 2)

        DataIntervalU = QLabel('ms', self)
        DataIntervalL = QLabel('Data Interval:', self)
        self.datainterval = QLineEdit(str(self.datainterval_val), self)
        self.gridlayout.addWidget(DataIntervalL, 12, 0)
        self.gridlayout.addWidget(self.datainterval, 12, 1)
        self.gridlayout.addWidget(DataIntervalU, 12, 2)

        BufferTimeU = QLabel('s', self)
        BufferTimeL = QLabel('Buffer Time:', self)
        self.buffertime = QLineEdit(str(self.buffertime_val), self)
        self.gridlayout.addWidget(BufferTimeL, 13, 0)
        self.gridlayout.addWidget(self.buffertime, 13, 1)
        self.gridlayout.addWidget(BufferTimeU, 13, 2)

        space = QLabel('', self)
        self.gridlayout.addWidget(space, 14, 0)


class MainWindow(QTabWidget):
    def __init__(self):
        super().__init__()
        self.initMe()

    def initMe(self):


        self.setGeometry(300, 150, 500, 600)
        self.setWindowTitle('Fishgrid.cfg')

        self.Grid = Grid_tab()
        self.addTab(self.Grid, 'Grid layout')

        self.HardWare = Hardware_settings_tab()
        self.addTab(self.HardWare, 'Hardware')

        self.Recording = Recording_settings()
        self.addTab(self.Recording, 'Recording')

        self.init_vars()

        if os.path.exists('/media/pi/data1/fishgrid.cfg'):
            cfg_file = '/media/pi/data1/fishgrid.cfg'
            self.read_cfg(cfg_file)

        elif 'fishgrid.cfg' in os.listdir('.'):
            cfg_file = './fishgrid.cfg'
            self.read_cfg(cfg_file)
        else:
            quit()


        self.Grid.get_widgets()
        self.HardWare.get_widgets()
        self.Recording.get_widgets()

        cancel = QPushButton('&Cancel', self)
        cancel.clicked.connect(self.closeMe)
        cancel.resize(100, 30)
        cancel.move(380, 550)

        save = QPushButton('&Save', self)
        save.clicked.connect(self.save_cfg)
        save.resize(100, 30)
        save.move(260, 550)

        self.show()

    def init_vars(self):
        self.Grid.columns_val = 8
        self.Grid.rows_val = 8
        self.Grid.col_dist_val = 50
        self.Grid.row_dist_val = 50
        self.Grid.channel_offset_val = 0
        self.Grid.elec_type_val = 'plain'
        self.Grid.ref_elec_type_val = 'plain'
        self.Grid.ref_elec_posx_val = 0.00
        self.Grid.ref_elec_posy_val = 0.00
        self.Grid.water_depth_val = 0.25

        self.HardWare.ai_sr_val = 20
        self.HardWare.ai_max_vol_val = 1
        self.HardWare.amp_name_val = "16-channel-amplifier"
        self.HardWare.amp_model_val = 'EM-64B'
        self.HardWare.amp_type_val = 'differential'
        self.HardWare.gain_val = 100
        self.HardWare.highpass_cutoff_val = 100
        self.HardWare.lowpass_cutoff_val = 10

        self.Recording.experiment_name_val = 'recording fish behavior'
        self.Recording.startdate_val = '~'
        self.Recording.starttime_val = '~'
        self.Recording.location_val = 'Colombia - Los Llanos'
        self.Recording.position_val = '~N, ~W'
        self.Recording.water_temp_val = 20
        self.Recording.water_cond_val = 5
        self.Recording.water_ph_val = 7
        self.Recording.water_oxy_val = 0
        self.Recording.comment_val = '~'
        self.Recording.experimenter_val = 'T. Raab et al. :)'
        self.Recording.datatime_val = 100
        self.Recording.datainterval_val = 1000
        self.Recording.buffertime_val = 60

    def closeMe(self):
        quit()

    def read_cfg(self, cfg_file):
        f = open(cfg_file, 'r')
        cfg = f.readlines()

        for line in cfg:

            if 'Columns1' in line:
                self.Grid.columns_val = int(line.split(':')[1].strip())
            elif 'Rows1' in line:
                self.Grid.rows_val = int(line.split(':')[1].strip())
            elif "ColumnDistance1" in line:
                self.Grid.col_dist_val = float(line.split(':')[-1].strip().replace('cm', ''))
            elif "RowDistance1" in line:
                self.Grid.row_dist_val = float(line.split(':')[-1].strip().replace('cm', ''))
            elif "ChannelOffset1" in line:
                self.Grid.channel_offset_val = int(line.split(':')[-1].strip())
            elif "ElectrodeType1" in line:
                self.Grid.elec_type_val = line.split(':')[-1].strip()
            elif "RefElectrodeType1" in line:
                self.Grid.ref_elec_type_val = line.split(":")[-1].strip()
            elif "RefElectrodePosX1" in line:
                self.Grid.ref_elec_posx_val = float(line.split(':')[-1].strip().replace('m', ''))
            elif 'RefElectrodePosY1' in line:
                self.Grid.ref_elec_posy_val = float(line.split(':')[-1].strip().replace('m', ''))
            elif 'WaterDepth1' in line:
                self.Grid.water_depth_val = float(line.split(':')[-1].strip().replace('m', ''))

            elif "AISampleRate" in line:
                self.HardWare.ai_sr_val = float(line.split(':')[-1].strip().replace('kHz', ''))
            elif "AIMaxVolt" in line:
                self.HardWare.ai_max_vol_val = float(line.split(':')[-1].strip().replace('mV', ''))
            elif "AmplName" in line:
                self.HardWare.amp_name_val = line.split(':')[-1].strip()
            elif "AmplModel" in line:
                self.HardWare.amp_model_val = line.split(':')[-1].strip()
            elif '  Type  ' in line:
                self.HardWare.amp_type_val = line.split(':')[-1].strip()
            elif 'Gain' in line:
                self.HardWare.gain_val = line.split(':')[-1].strip()
            elif "HighpassCutoff" in line:
                self.HardWare.highpass_cutoff_val = int(line.split(':')[-1].strip().replace('Hz', ''))
            elif 'LowpassCutoff' in line:
                self.HardWare.lowpass_cutoff_val = float(line.split(':')[-1].strip().replace('kHz', ''))

            elif "Experiment.Name" in line:
                self.Recording.experiment_name_val = line.split(':')[-1].strip()
            elif "StartDate" in line:
                self.Recording.startdate_val = line.split(':')[-1].strip()
            elif "StartTime" in line:
                self.Recording.starttime_val = ':'.join(line.split(':')[1:]).strip()
            elif "Location" in line:
                self.Recording.location_val = line.split(':')[-1].strip()
            elif "Position" in line:
                self.Recording.position_val = line.split(':')[-1].strip()
            elif "WaterTemperature" in line:
                self.Recording.water_temp_val = float(line.split(':')[-1].strip().replace('C', ''))
            elif "WaterConductivity" in line:
                self.Recording.water_cond_val = float(line.split(':')[-1].strip().replace('uS/cm', ''))
            elif 'WaterpH' in line:
                self.Recording.water_ph_val = float(line.split(':')[-1].strip().replace('pH', ''))
            elif "WaterOxygen" in line:
                self.Recording.water_oxy_val = float(line.split(':')[-1].strip().replace('mg/l', ''))
            elif "Comment" in line:
                self.Recording.comment_val = ':'.join(line.split(':')[1:]).strip()
            elif "Experimenter" in line:
                self.Recording.experimenter_val = ':'.join(line.split(':')[1:]).strip()
            elif "DataTime" in line:
                self.Recording.datatime_val = int(line.split(':')[-1].strip().replace('ms', ''))
            elif "DataInterval" in line:
                self.Recording.datainterval_val = int(line.split(':')[-1].strip().replace('ms', ''))
            elif "BufferTime" in line:
                self.Recording.buffertime_val = int(line.split(':')[-1].strip().replace('s', ''))
            else:
                continue

    def save_cfg(self):
        if os.path.exists('/media/pi/data1/fishgrid.cfg'):
            f = open('/media/pi/data1/fishgrid.cfg', 'w+')
        else:
            f = open('./fishgrid.cfg', 'w+')
        # ToDo: 'grid no.'
        f.write('*FishGrid\n')
        f.write('  Grid &1:\n')
        f.write('      Used1            : true\n')
        f.write('      Gridno1          : 1\n')
        f.write('      Columns1         : %.0f\n' % int(self.Grid.col_elecs.text()))
        f.write('      Rows1            : %.0f\n' % int(self.Grid.row_elecs.text()))
        f.write('      ColumnDistance1  : %.1fcm\n' % float(self.Grid.col_space.text()))
        f.write('      RowDistance1     : %.1fcm\n' % float(self.Grid.row_space.text()))
        # f.write('      ChannelOffset1   : %.0f\n' % int(self.Grid.channel_offset.text()))
        f.write('      ElectrodeType1   : %s\n' % self.Grid.elec_type.text()) # ToDo: 'headstage'
        f.write('      RefElectrodeType1: %s\n' % self.Grid.ref_elec_type.text()) # ToDo: 'screw'
        f.write('      RefElectrodePosX1: %.2fm\n' % float(self.Grid.ref_elec_x.text()))
        f.write('      RefElectrodePosY1: %.2fm\n' % float(self.Grid.ref_elec_y.text()))
        f.write('      WaterDepth1      : %.2fm\n' % float(self.Grid.water_depth.text()))
        f.write('  Hardware Settings:\n')
        f.write('      DAQ board:\n')
        f.write('          AISampleRate: %.3fkHz\n' % float(self.HardWare.AIsr.text()))
        f.write('          AIMaxVolt   : %.1fmV\n' % float(self.HardWare.AImaxV.text()))
        f.write('      Amplifier:\n')
        f.write('          AmplName      : %s\n' % self.HardWare.AmplName.text())
        f.write('          AmplModel     : %s\n' % self.HardWare.AmplModel.text())
        f.write('          Type          : %s\n' % self.HardWare.AmplType.text())
        f.write('          Gain          : %.0f\n' % int(self.HardWare.gain.text()))
        f.write('          HighpassCutoff: %.0fHz\n' % int(self.HardWare.hp_cutoff.text()))
        f.write('          LowpassCutoff : %.3fkHz\n' % float(self.HardWare.lp_cutoff.text()))
        f.write('  Recording:\n')
        f.write('      General:\n')
        f.write('          Experiment.Name  : %s\n' % self.Recording.exp_name.text())
        f.write('          StartDate        : %s\n' % self.Recording.start_date.text())
        f.write('          StartTime        : %s\n' % self.Recording.start_time.text())
        f.write('          Location         : %s\n' % self.Recording.location.text())
        f.write('          Position         : %s\n' % self.Recording.position.text())
        f.write('          WaterTemperature : %.1fC\n' % float(self.Recording.waterTemp.text()))
        f.write('          WaterConductivity: %.1fuS/cm\n' % float(self.Recording.waterCond.text()))
        f.write('          WaterpH          : %.1fpH\n' % float(self.Recording.waterpH.text()))
        f.write('          WaterOxygen      : %.1fmg/l\n' % float(self.Recording.waterOxy.text()))
        f.write('          Comment          : %s\n' % self.Recording.comment.text())
        f.write('          Experimenter     : %s\n' % self.Recording.experimenter.text())
        # f.write('      Buffers and timing:\n')
        # f.write('          DataTime    : %.0fms\n' % float(self.Recording.datatime.text()))
        # f.write('          DataInterval: %.0fms\n' % float(self.Recording.datainterval.text()))
        # f.write('          BufferTime  : %.0fs\n' % float(self.Recording.buffertime.text()))
        f.write('*Recording\n')
        f.write('  PathFormat: "%04Y-%02m-%02d-%02H_%02M"\n')
        f.close()

        exit()


def main():
    app = QApplication(sys.argv)  # create application
    w = MainWindow()  # create window

    sys.exit(app.exec_())  # exit if window is closed


if __name__ == '__main__':
    main()