import numpy as np
import pandas as pd
import random, os, json
import ensayos_motor as ensayo

def valores_objetivo(archivo, material):
    resistencia = 4.5

    E_obj, f = ensayo.ensayar_material(resistencia, material, archivo)
    
    return E_obj, f


def generar_curva(offset, ruta):

    muVacio = 4 * np.pi * 1e-7

    with open("h_values/h_values.json", "r") as f : h = np.array(json.load(f))
    b = muVacio * h + offset

    with open(ruta, "w") as f:
        f.write('[PLACond]\n')
        f.write('Type=Fixed_Solid\n')
        f.write('Solid Type=Steel\n')
        f.write('Thermal Conductivity=0\n')
        f.write('Specific Heat=0\n')
        f.write('Density=1850\n')
        f.write('Notes=\n')
        f.write('ElectricalResistivity=0.2\n')
        f.write('TempCoefElectricalResistivity=0\n')
        f.write('PoissonsRatio=0\n')
        f.write('YoungsCoefficient=0\n')
        f.write('YieldStress=0\n')
        f.write(f'BValue[0]=0\n')
        f.write(f'HValue[0]=0\n')

        for i in np.arange(len(h)):
            f.write(f'BValue[{i+1}]={b[i]}\n')
            f.write(f'HValue[{i+1}]={h[i]}\n')
            
    print("Curva generada correctamente en: ", ruta)

def logica_offset(offset, error, errorObjetivo):
    '''
    Coge el offset, error actual y lo analiza.

    devuelve flag y offset nuevo

    si se cumple la condicion devuelve 
    un True y None para offset

    '''

    limSup = 1 + errorObjetivo
    limInf = 1 - errorObjetivo

    if error <= limSup and error >= limInf: return True, None

    tasa_aprendizaje = 0.001

    desviacion = error - 1
    delta = abs(tasa_aprendizaje * np.tanh(desviacion))

    print(delta)

    if error >= limSup: offset -= delta
    if error <= limInf: offset += delta

    return False, offset



if __name__ == '__main__':
    '''
    Esto solo se activa si se lanza este script en concreto
    no si se invocan las funciones desde otro script.

    Contiene ejemplos de como funciona el codigo para ver
    como funciona todo

    '''

    directorio = ''
    nombre = "PLACond.mdb"

    ruta = f'{directorio}{nombre}'
    offset = 0

    E_original = 70
    
    B = 4 * np.pi * 1e-7 * 1000 + offset

    cte = E_original/B

    EObjetivo = 175

    errorObjetivo = 0.01

    flag = False

    while flag == False:
        os.system('cls')

        B_nuevo = 4 * np.pi * 1e-7 * 1000 + offset

        Ecalculado = cte * B_nuevo

        error = Ecalculado/EObjetivo

        print(Ecalculado)
        print(error)
        print()

        flag, offset = logica_offset(offset, error, errorObjetivo)
