pm1_str = """A01	Negative Control	
A02	L-Arabinose	cpd00224
A03	N-Acetyl-DGlucosamine	cpd00122
A04	D-Saccharic Acid	cpd00571
A05	Succinic Acid	cpd00036
A06	D-Galactose	cpd00108
A07	L-Aspartic Acid	cpd00041
A08	L-Proline	cpd00129
A09	D-Alanine	cpd00117
A10	D-Trehalose	cpd00794
A11	D-Mannose	cpd00138
A12	Dulcitol 	cpd01171
B01	D-Serine	cpd00550
B02	D-Sorbitol	cpd00588
B03	Glycerol	cpd00100
B04	L-Fucose	cpd00751
B05	D-Glucuronic Acid	
B06	D-Gluconic Acid	
B07	D,L-α-GlycerolPhosphate	
B08	D-Xylose	cpd00154
B09	L-Lactic Acid	cpd00159
B10	Formic Acid	cpd00047
B11	D-Mannitol	cpd00314
B12	L-Glutamic Acid	cpd00023
C01	Glucose-6-Phosphate	cpd00079
C02	D-Galactonic Acid-γ-Lactone	cpd02143
C03	D,L-Malic Acid	cpd00130;cpd00386
C04	D-Ribose	cpd00105
C05	Tween 20	cpd13391;cpd01741
C06	L-Rhamnose	cpd00396
C07	D-Fructose	cpd00082
C08	Acetic Acid	cpd00029
C09	α-D-Glucose	cpd00027
C10	Maltose	cpd00179
C11	D-Melibiose	cpd03198
C12	Thymidine 	cpd00184
D01	L-Asparagine	cpd00132
D02	D-Aspartic Acid	cpd00320
D03	D-Glucosaminic Acid	cpd02351
D04	1,2-Propanediol	cpd01861
D05	Tween 40	cpd24417;cpd00214
D06	α-Keto-Glutaric Acid	cpd00024
D07	α-Keto-Butyric Acid	cpd00094
D08	α-Methyl-DGalactoside	
D09	α-D-Lactose	cpd00208
D10	Lactulose	cpd04349
D11	Sucrose	cpd00076
D12	Uridine 	cpd00249
E01	L-Glutamine	cpd00053
E02	M-Tartaric Acid	cpd00432
E03	Glucose-1-Phosphate	cpd00089
E04	Fructose-6-Phosphate	cpd00072
E05	Tween 80	cpd13392
E06	α-Hydroxy Glutaric Acid-γLactone	cpd23862
E07	α-Hydroxy Butyric Acid	
E08	β-Methyl-DGlucoside	
E09	Adonitol	cpd00366
E10	Maltotriose	cpd01262
E11	2-Deoxy Adenosine	cpd00115
E12	Adenosine 	cpd00182
F01	Glycyl-L-Aspartic Acid	cpd11589
F02	Citric Acid	cpd00137
F03	M-Inositol	cpd00121
F04	D-Threonine	cpd00611
F05	Fumaric Acid	cpd00106
F06	Bromo Succinic Acid	cpd23859
F07	Propionic Acid	
F08	Mucic Acid	
F09	Glycolic Acid	cpd00139
F10	Glyoxylic Acid	cpd00040
F11	D-Cellobiose	
F12	Inosine 	cpd00246
G01	Glycyl-L-Glutamic Acid	
G02	Tricarballylic Acid	cpd16654
G03	L-Serine	cpd00054
G04	L-Threonine	cpd00161
G05	L-Alanine	cpd00035
G06	L-Alanyl-Glycine	
G07	Acetoacetic Acid	cpd00142
G08	N-Acetyl-β-D-Mannosamine	
G09	Mono Methyl Succinate	
G10	Methyl Pyruvate	cpd24420
G11	D-Malic Acid	cpd00386
G12	L-Malic Acid	cpd00130
H01	Glycyl-L-Proline	
H02	P-Hydroxy Phenyl Acetic Acid	
H03	M-Hydroxy Phenyl Acetic Acid	
H04	Tyramine	cpd00374
H05	D-Psicose	cpd03884
H06	L-Lyxose	cpd01067
H07	Glucuronamide	cpd26269
H08	Pyruvic Acid	cpd00020
H09	L-Galactonic Acid-γ-Lactone	
H10	D-Galacturonic Acid	
H11	Phenylethylamine	cpd03161
H12	2-Aminoethano	cpd00162"""


class BiologPlate:

    def __init__(self, plate_id, rows, cols):
        self.id = plate_id
        self.rows = rows
        self.cols = cols
        self.wells = {}
        self.base = {}

    def add_base(self, compounds, value):
        for c in compounds:
            self.base[c] = value

    def get_media(self, well_id):
        media = {}
        if well_id in self.wells:
            well = self.wells[well_id]
            for compound in self.base:
                media[compound] = self.base[compound]
            for compound in well['compounds']:
                media[compound] = well['value']
            return media
        else:
            return None

    def _repr_html_(self):
        html = "<h3>" + self.id + "</h3>"
        t = '<table style="border-width: 1px; box-sizing: border-box; border-color: grey"><tbody>'
        for row in self.rows:
            t += "<tr>"
            for col in self.cols:
                t += '<td style="text-align:left;vertical-align:top;">'
                for o in self.wells:
                    if o == row + col:
                        t += self.wells[o]['desc']
                        # print(self.wells[o])
                t += "</td>"
            t += "</tr>"
        t += "</tbody></table>"
        html += t
        return html


class Biolog:

    def __init__(self):
        self.plates = {}

    def add_plate(self, plate):
        if plate.id in self.plates:
            print('replace existing plate')
        self.plates[plate.id] = plate

    def run_plates(self, model, biomass=None, cmp='e'):
        # model.objective = biomass
        prev_medium = model.medium
        compound_exchange = {}
        for o in model.exchanges:
            m = list(o.metabolites)[0]
            if m.id not in compound_exchange:
                compound_exchange[m.id] = o
            else:
                print(o, list(o.metabolites)[0])
        for plate_id in self.plates:
            plate = self.plates[plate_id]
            for well_id in plate.wells:
                media = plate.get_media(well_id)
                model_medium = {}
                for o in media:
                    match = "{}_{}".format(o, cmp)
                    if match in compound_exchange:
                        model_medium[compound_exchange[match].id] = media[o]
                    else:
                        print('skip', o)
                model.medium = model_medium
                ovalue = model.slim_optimize()
                plate.wells[well_id]['growth'] = ovalue
                # print(well_id, solution)
                # print(well_id, media)
        return prev_medium
