import analytical
import num_losere
import constants as c
import numpy as np

import matplotlib.pyplot as plt
from IPython.display import display
import ipywidgets as wid
import datetime

def main(t = 1, T = 1000, solver = 'Implicit', dt = c.dx_imp, end_time = c.t_stop):
    if solver == 'Implicit':
        C, x_points = num_losere.implisitt(T=T, t_stop=end_time, dt=dt)
        dx = c.dx_imp
    elif solver == 'Explicit':
        C, x_points = num_losere.eksplisitt(T = T, t_stop=end_time, dt=dt)
        dx = round(x_points[1] - x_points[0], 2)
    elif solver == 'Crank-Nicholson':
        C, x_points = num_losere.crank_nicholson(T=T, t_stop=end_time, dt=dt)
        dx = c.dx_crank

    time_step = int(t/dt)-1
    analytisk_c = analytical.cons(x_points, t, T = T)

    plt.plot(x_points, C[time_step], color = 'blue', label= solver + ' numerical solution'
                                                        '\ndx = '+str(dx)+'mm, dt = '+str(dt)+'s')
    plt.plot(-x_points, C[time_step], color = 'blue')
    plt.plot(x_points, analytisk_c, color = 'orange', linestyle = '--',
             label = 'Analytical solution, k = '+ str(c.analytical_k))
    plt.plot(-x_points, analytisk_c, color = 'orange', linestyle = '--')

    timestr = str(datetime.timedelta(seconds=t))
    timestr = " " * (6 - len(timestr)) + timestr
    total_cons = np.mean(C[time_step][1:-1])


    plt.legend()
    plt.title('Time : ' + timestr +
                      "\nTemperature : " + str(T) + "K"
                        "\nTotal concentration : " + str(round(total_cons, 2)) + 'wt%')
    plt.xlabel('Position [mm]')
    plt.ylabel('Concentration [wt%]')
    plt.ylim(0, max([c.C0, c.Cs]))
    plt.xlim(-c.L / 2, c.L / 2)

    plt.show()

def run():
    Temp = wid.IntText(value = 1273, description = 'Temp [K]')
    tid = wid.IntText(value=1, description='Time [s]')
    dt = wid.IntSlider(min=1, max = 50, step=1, description = 'dt [s]')
    play = wid.Play(value=0, min=1, max=c.t_stop, step=c.speed)
    solver = wid.Dropdown(options=['Explicit', 'Implicit', 'Crank-Nicholson'], description = 'Solver :')

    wid.jslink((play, 'value'), (tid, 'value'))

    controls = wid.VBox([wid.HBox([solver, Temp, dt]),wid.HBox([play, tid])])

    output = wid.interactive(main, t = tid, T = Temp, solver = solver, dt = dt)
    display(wid.VBox([controls, output.children[-1]]))
