# PC 204 Final Project
# Python 3.4
# Module 3

import numpy as np
import math

class Final(object):
    result = []
    data = []
    from_module = 'A'

    #initializes based on data type. If it's a tuple, then data is an array of arrays.
    def __init__(self, data):
        self.data = data
        if len(data) == 3: #B has an output with length=3
            #self.data = data
            self.from_module = 'B'


    def calculate(self):
        # range for k, double check for off by one

        CL = [x for x in np.arange(1,3,0.1)]
        LZB = []
        for element in CL:
            LZB.append(1.18*math.exp(-0.42*element)+1.24)

        if self.from_module == 'A':
            Ce = [] #concentration of effect compartment
            for index_row in range(len(self.data)):
                Ce.append(self.data[index_row][1])

            max_index = Ce.index(max(Ce))

            Cesub = Ce[max_index:] #sub list of Ce, starting from peak to end

            min_distance = 10000 #initial
            closest_index = -1#initial

            #find the index of Ce in which Ce has passed its peak concentration
            #then crosses or is closest to 0.2*max(Ce)
            for index in range(len(Cesub)):
                if(abs(Cesub[index] - 0.2*max(Ce)) < min_distance ):
                    min_distance = abs(Cesub[index] - 0.2*max(Ce))
                    closest_index = index
            safety_factor = Ce[closest_index]

            output = []
            for element in LZB:
                output.append(safety_factor * element)

            if output[0] < 0:
                print("Warning: the set of input parameter values led to physiologically meangingless outcome")
            self.result = output

            #self.max_val = max(self.data)
            #self.result += [self.max_val for x in range(len(self.data))]
        elif self.from_module == 'B':
            Cp1 = []
            Cp2 = []
            Cp3 = []
            #extract concentration information from the
            #matrix output of module 2 (Model B)
            for index_row in range(len(self.data[0])):
                Cp1.append(self.data[0][index_row][1])

            for index_row in range(len(self.data[0])):
                Cp2.append(self.data[1][index_row][1])

            for index_row in range(len(self.data[0])):
                Cp3.append(self.data[2][index_row][1])

            peak1 = max(Cp1)
            peak2 = max(Cp2)
            peak3 = max(Cp3)

            output1 = []
            output2 = []
            output3 = []
            for element in LZB:
                output1.append(peak1 * element)
                output2.append(peak2 * element)
                output3.append(peak3 * element)

            if output1[0] < 0:
                print("Warning: the set of input parameter values led to physiologically meangingless outcome")
            if output2[0] < 0:
                print("Warning: the set of input parameter values led to physiologically meangingless outcome")
            if output3[0] < 0:
                print("Warning: the set of input parameter values led to physiologically meangingless outcome")
            self.result = [output1, output2, output3]

        #print(self.result)
        return self.result