import numpy as np
import networkx as nx
import random as pr
import matplotlib.pyplot as pl
import pp
import time
import copy
import sys
import os
import PIL
from Tkinter import *
import tkFileDialog
import tkSimpleDialog
import tkMessageBox
from fomite_ABM import *
from math import *
from PIL import Image
from PIL import ImageTk

global image1
global image2

def vp_start_gui():
    '''Starting point when module is the main routine.'''
    global val, w, root, top, mod, dummy1, dummy2, dummy3, dummy4
    global parameters
    mod = 0
    parameters = {'contactRateHH':0.0, 'contactRateHF':0.0, 'pickupFr':0.0, 'transferFr':0.0, 'faceTouchRate':0.0, 'infProb':0.0, 'washRate':0.0, 'incubationRate':0.0, 'recoveryRate':0.0, 'sheddingRate':0.0, 'shedding':0.0, 'dieOff':0.0, 'deconFreq':None, 'dayLength':0.0}
    root = Tk()
    top = New_Toplevel_1 (root)
    root.protocol('WM_DELETE_WINDOW',lambda: close())
    dummy1 = open('fig1.png', 'w')
    dummy2 = open('fig2.png', 'w')
    dummy3 = open('fig3.png', 'w')
    dummy4 = open('fig4.png', 'w')
    root.resizable(width=False, height=False)
    root.mainloop()

def close():
    #check for extraneous/duplicates
    dummy1.close()
    dummy2.close()
    dummy3.close()
    dummy4.close()
    os.remove('fig1.png')
    os.remove('fig2.png')
    os.remove('fig3.png')
    os.remove('fig4.png')
    root.destroy()

class New_Toplevel_1:
    def __init__(self, top=None):
        '''This class configures and populates the toplevel window.
           top is the toplevel containing window.'''
        _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
        _fgcolor = '#000000'  # X11 color: 'black'
        _compcolor = '#d9d9d9' # X11 color: 'gray85'
        _ana1color = '#d9d9d9' # X11 color: 'gray85'
        _ana2color = '#d9d9d9' # X11 color: 'gray85'
        font10 = "-family {DejaVu Sans Mono} -size 15 -weight normal "  \
            "-slant roman -underline 0 -overstrike 1"
        font11 = "-family {DejaVu Sans Mono} -size 15 -weight bold "  \
            "-slant roman -underline 0 -overstrike 0"
        font9 = "-family {DejaVu Sans Mono} -size 15 -weight normal "  \
            "-slant roman -underline 0 -overstrike 0"

        global days, agents
        days = 10
        agents = 20
        top.geometry("1031x593+89+80")
        top.title('Maize & Blue SIWR v2.11')
        top.configure(background="#135bd9")
        top.configure(highlightcolor="black")
        top.configure(cursor='pencil')

        self.Label1 = Label(top)
        self.Label1.place(relx=0.01, rely=0.03, height=18, width=126)
        self.Label1.configure(activebackground="#135bd9")
        self.Label1.configure(activeforeground="white")
        self.Label1.configure(background="#135bd9")
        self.Label1.configure(text='''Contact Rate HH''')

        self.Label15 = Label(top)
        self.Label15.place(relx=0.03, rely=0.07, height=18, width=126)
        self.Label15.configure(activebackground="#f9f9f9")
        self.Label15.configure(background="#135bd9")
        self.Label15.configure(text='''Contact Rate HF''')

        self.Label14 = Label(top)
        self.Label14.place(relx=-.01, rely=0.11, height=18, width=126)
        self.Label14.configure(activebackground="#f9f9f9")
        self.Label14.configure(background="#135bd9")
        self.Label14.configure(text='''Pickup FR''')

        self.Label5 = Label(top)
        self.Label5.place(relx=0.015, rely=0.15, height=18, width=126)
        self.Label5.configure(activebackground="#f9f9f9")
        self.Label5.configure(background="#135bd9")
        self.Label5.configure(text='''Transfer FR''')

        self.Label4 = Label(top)
        self.Label4.place(relx=0.01, rely=0.19, height=18, width=126)
        self.Label4.configure(activebackground="#f9f9f9")
        self.Label4.configure(background="#135bd9")
        self.Label4.configure(text='''Face Touch Rate''')

        self.Label6 = Label(top)
        self.Label6.place(relx=0.008, rely=0.23, height=18, width=126)
        self.Label6.configure(activebackground="#f9f9f9")
        self.Label6.configure(background="#135bd9")
        self.Label6.configure(text='''INF Prob''')

        self.Label7 = Label(top)
        self.Label7.place(relx=-.01, rely=0.27, height=18, width=126)
        self.Label7.configure(activebackground="#f9f9f9")
        self.Label7.configure(background="#135bd9")
        self.Label7.configure(text='''Wash Rate''')

        self.Label8 = Label(top)
        self.Label8.place(relx=0.03, rely=0.31, height=18, width=126)
        self.Label8.configure(activebackground="#f9f9f9")
        self.Label8.configure(background="#135bd9")
        self.Label8.configure(text='''Incubation Rate''')

        self.Label9 = Label(top)
        self.Label9.place(relx=0.003, rely=0.35, height=18, width=126)
        self.Label9.configure(activebackground="#f9f9f9")
        self.Label9.configure(background="#135bd9")
        self.Label9.configure(text='''Recovery Rate''')

        self.Label10 = Label(top)
        self.Label10.place(relx=0.027, rely=0.39, height=18, width=126)
        self.Label10.configure(activebackground="#f9f9f9")
        self.Label10.configure(background="#135bd9")
        self.Label10.configure(text='''Shedding Rate''')

        self.Label11 = Label(top)
        self.Label11.place(relx=-.01, rely=0.43, height=18, width=126)
        self.Label11.configure(activebackground="#f9f9f9")
        self.Label11.configure(background="#135bd9")
        self.Label11.configure(text='''Shedding''')

        self.Label12 = Label(top)
        self.Label12.place(relx=0.00, rely=0.47, height=18, width=126)
        self.Label12.configure(activebackground="#f9f9f9")
        self.Label12.configure(background="#135bd9")
        self.Label12.configure(text='''Dieoff''')

        self.Label3 = Label(top)
        self.Label3.place(relx=-.003, rely=0.51, height=18, width=126)
        self.Label3.configure(activebackground="#f9f9f9")
        self.Label3.configure(background="#135bd9")
        self.Label3.configure(text='''Decon Freq''')

        self.Label13 = Label(top)
        self.Label13.place(relx=0.018, rely=0.55, height=18, width=126)
        self.Label13.configure(activebackground="#f9f9f9")
        self.Label13.configure(background="#135bd9")
        self.Label13.configure(text='''Day Length''')

        self.Entry1 = Entry(top)
        self.Entry1.place(relx=0.17, rely=0.03, relheight=0.03, relwidth=0.14)
        self.Entry1.configure(background="white")
        self.Entry1.configure(font="TkFixedFont")
        self.Entry1.configure(selectbackground="#c4c4c4")

        self.Entry2 = Entry(top)
        self.Entry2.place(relx=0.19, rely=0.07, relheight=0.03, relwidth=0.14)
        self.Entry2.configure(background="white")
        self.Entry2.configure(font="TkFixedFont")
        self.Entry2.configure(selectbackground="#c4c4c4")

        self.Entry3 = Entry(top)
        self.Entry3.place(relx=0.17, rely=0.11, relheight=0.03, relwidth=0.14)
        self.Entry3.configure(background="white")
        self.Entry3.configure(font="TkFixedFont")
        self.Entry3.configure(selectbackground="#c4c4c4")

        self.Entry4 = Entry(top)
        self.Entry4.place(relx=0.19, rely=0.15, relheight=0.03, relwidth=0.14)
        self.Entry4.configure(background="white")
        self.Entry4.configure(font="TkFixedFont")
        self.Entry4.configure(selectbackground="#c4c4c4")

        self.Entry5 = Entry(top)
        self.Entry5.place(relx=0.17, rely=0.19, relheight=0.03, relwidth=0.14)
        self.Entry5.configure(background="white")
        self.Entry5.configure(font="TkFixedFont")
        self.Entry5.configure(selectbackground="#c4c4c4")

        self.Entry6 = Entry(top)
        self.Entry6.place(relx=0.19, rely=0.23, relheight=0.03, relwidth=0.14)
        self.Entry6.configure(background="white")
        self.Entry6.configure(font="TkFixedFont")
        self.Entry6.configure(selectbackground="#c4c4c4")

        self.Entry7 = Entry(top)
        self.Entry7.place(relx=0.17, rely=0.27, relheight=0.03, relwidth=0.14)
        self.Entry7.configure(background="white")
        self.Entry7.configure(font="TkFixedFont")
        self.Entry7.configure(selectbackground="#c4c4c4")

        self.Entry8 = Entry(top)
        self.Entry8.place(relx=0.19, rely=0.31, relheight=0.03, relwidth=0.14)
        self.Entry8.configure(background="white")
        self.Entry8.configure(font="TkFixedFont")
        self.Entry8.configure(selectbackground="#c4c4c4")

        self.Entry9 = Entry(top)
        self.Entry9.place(relx=0.17, rely=0.35, relheight=0.03, relwidth=0.14)
        self.Entry9.configure(background="white")
        self.Entry9.configure(font="TkFixedFont")
        self.Entry9.configure(selectbackground="#c4c4c4")

        self.Entry10 = Entry(top)
        self.Entry10.place(relx=0.19, rely=0.39, relheight=0.03, relwidth=0.14)
        self.Entry10.configure(background="white")
        self.Entry10.configure(font="TkFixedFont")
        self.Entry10.configure(selectbackground="#c4c4c4")

        self.Entry11 = Entry(top)
        self.Entry11.place(relx=0.17, rely=0.43, relheight=0.03, relwidth=0.14)
        self.Entry11.configure(background="white")
        self.Entry11.configure(font="TkFixedFont")
        self.Entry11.configure(selectbackground="#c4c4c4")

        self.Entry12 = Entry(top)
        self.Entry12.place(relx=0.19, rely=0.47, relheight=0.03, relwidth=0.14)
        self.Entry12.configure(background="white")
        self.Entry12.configure(font="TkFixedFont")
        self.Entry12.configure(selectbackground="#c4c4c4")

        self.Entry13 = Entry(top)
        self.Entry13.place(relx=0.17, rely=0.51, relheight=0.03, relwidth=0.14)
        self.Entry13.configure(background="white")
        self.Entry13.configure(font="TkFixedFont")
        self.Entry13.configure(selectbackground="#c4c4c4")

        self.Entry14 = Entry(top)
        self.Entry14.place(relx=0.19, rely=0.55, relheight=0.03, relwidth=0.14)
        self.Entry14.configure(background="white")
        self.Entry14.configure(font="TkFixedFont")
        self.Entry14.configure(selectbackground="#c4c4c4")

        self.Button1 = Button(top)
        self.Button1.place(relx=0.02, rely=0.65, height=26, width=157)
        self.Button1.configure(activebackground="#d9d9d9")
        self.Button1.configure(background="#d9d938")
        self.Button1.configure(font=font9)
        self.Button1.configure(text='''Save''')
        self.Button1.configure(cursor='crosshair')
        self.Button1.configure(command=lambda: but1Press())

        self.Button2 = Button(top)
        self.Button2.place(relx=0.18, rely=0.65, height=26, width=157)
        self.Button2.configure(activebackground="#d9d9d9")
        self.Button2.configure(background="#d9d938")
        self.Button2.configure(font=font9)
        self.Button2.configure(text='''Load''')
        self.Button2.configure(cursor='crosshair')
        self.Button2.configure(command=lambda: but2Press())

        self.Button3 = Button(top)
        self.Button3.place(relx=0.02, rely=0.71, height=26, width=157)
        self.Button3.configure(activebackground="#d9d9d9")
        self.Button3.configure(background="#d9d938")
        self.Button3.configure(font=font11)
        self.Button3.configure(text='''Generate''')
        self.Button3.configure(cursor='crosshair')
        self.Button3.configure(command=lambda: but3Press())

        self.Button4 = Button(top)
        self.Button4.place(relx=0.18, rely=0.71, height=26, width=157)
        self.Button4.configure(activebackground="#d9d9d9")
        self.Button4.configure(background="#d9d938")
        self.Button4.configure(font=font10)
        self.Button4.configure(text='''Clear''')
        self.Button4.configure(cursor='crosshair')
        self.Button4.configure(command=lambda: but4Press())

        self.Button6 = Button(top)
        self.Button6.place(relx=0.02, rely=0.80, height=26, width=322)
        self.Button6.configure(activebackground="#d9d9d9")
        self.Button6.configure(background="#d9d938")
        self.Button6.configure(font=font9)
        self.Button6.configure(text='''Economic Analysis''')
        self.Button6.configure(cursor='crosshair')
        self.Button6.configure(command=lambda: but6Press())

        self.Button7 = Button(top)
        self.Button7.place(relx=0.02, rely=0.86, height=26, width=322)
        self.Button7.configure(activebackground="#d9d9d9")
        self.Button7.configure(background="#d9d938")
        self.Button7.configure(font=font9)
        self.Button7.configure(text='''Curve Interpolation''')
        self.Button7.configure(cursor='crosshair')
        self.Button7.configure(command=lambda: but7Press())

        self.Button8 = Button(top)
        self.Button8.place(relx=0.02, rely=0.92, height=26, width=322)
        self.Button8.configure(activebackground="#d9d9d9")
        self.Button8.configure(background="#d9d938")
        self.Button8.configure(font=font9)
        self.Button8.configure(text='''Oppa Gangnam Style''')
        self.Button8.configure(cursor='crosshair')
        self.Button8.configure(command=lambda: but8Press())

        self.Label2 = Label(top)
        self.Label2.place(relx=0.4, rely=0.03, height=18, width=33)
        self.Label2.configure(activebackground="#f9f9f9")
        self.Label2.configure(background="#135bd9")
        self.Label2.configure(text='''Days''')

        self.Entry15 = Entry(top)
        self.Entry15.place(relx=0.44, rely=0.03, relheight=0.03, relwidth=0.14)
        self.Entry15.configure(background="white")
        self.Entry15.configure(font="TkFixedFont")
        self.Entry15.configure(selectbackground="#c4c4c4")
        self.Entry15.insert(0,days)

        self.Label16 = Label(top)
        self.Label16.place(relx=0.6, rely=0.03, height=18, width=51)
        self.Label16.configure(activebackground="#f9f9f9")
        self.Label16.configure(background="#135bd9")
        self.Label16.configure(text='''Agents''')

        self.Entry16 = Entry(top)
        self.Entry16.place(relx=0.656, rely=0.03, relheight=0.03, relwidth=0.14)
        self.Entry16.configure(background="white")
        self.Entry16.configure(font="TkFixedFont")
        self.Entry16.configure(selectbackground="#c4c4c4")
        self.Entry16.insert(0,agents)

        self.Button5 = Button(top)
        self.Button5.place(relx=0.4, rely=0.12, height=486, width=587)
        self.Button5.configure(activebackground="#d9d9d9")
        self.Button5.configure(state=ACTIVE)
        self.Button5.configure(cursor='exchange')
        self.Button5.configure(command=lambda: but5Press())

    def take(self):
        global days, agents
        self.entries = []
        self.entries.append(self.Entry1.get())
        self.entries.append(self.Entry2.get())
        self.entries.append(self.Entry3.get())
        self.entries.append(self.Entry4.get())
        self.entries.append(self.Entry5.get())
        self.entries.append(self.Entry6.get())
        self.entries.append(self.Entry7.get())
        self.entries.append(self.Entry8.get())
        self.entries.append(self.Entry9.get())
        self.entries.append(self.Entry10.get())
        self.entries.append(self.Entry11.get())
        self.entries.append(self.Entry12.get())
        self.entries.append(self.Entry13.get())
        self.entries.append(self.Entry14.get())
        days = int(self.Entry15.get())
        agents = int(self.Entry16.get())

    def give(self, vals=[]):
        print(vals)
        self.Entry1.insert(0,vals[0])
        self.Entry2.insert(0,vals[1])
        self.Entry3.insert(0,vals[2])
        self.Entry4.insert(0,vals[3])
        self.Entry5.insert(0,vals[4])
        self.Entry6.insert(0,vals[5])
        self.Entry7.insert(0,vals[6])
        self.Entry8.insert(0,vals[7])
        self.Entry9.insert(0,vals[8])
        self.Entry10.insert(0,vals[9])
        self.Entry11.insert(0,vals[10])
        self.Entry12.insert(0,vals[11])
        self.Entry13.insert(0,vals[12])
        self.Entry14.insert(0,vals[13])

    def _set_out(self, val, agents):
        self._total = val
        self._agents = agents

def but1Press():
    dialog = tkSimpleDialog.askstring('SIWR Input', 'Input a file name:')
    dialog += '.siwr'
    out = open(dialog, 'w')
    top.take()
    for x in top.entries:
        out.write(x)
        out.write(' ')

def but2Press():
    name = tkFileDialog.askopenfilename()
    out = open(name, 'r')
    params = out.read().split()
    top.give(params)

def but3Press():
    global parameters
    top.take()
    parameters['contactRateHH'] = float(top.entries[0])
    parameters['contactRateHF'] = float(top.entries[1])
    parameters['pickupFr'] = float(top.entries[2])
    parameters['transferFr'] = float(top.entries[3])
    parameters['faceTouchRate'] = float(top.entries[4])
    parameters['infProb'] = float(top.entries[5])
    parameters['washRate'] = float(top.entries[6])
    parameters['incubationRate'] = float(top.entries[7])
    parameters['recoveryRate'] = float(top.entries[8])
    parameters['sheddingRate'] = float(top.entries[9])
    parameters['shedding'] = float(top.entries[10])
    parameters['dieOff'] = float(top.entries[11])
    if(float(top.entries[12]) != 0):
        parameters['deconFreq'] = float(top.entries[12])
    else:
        parameters['deconFreq'] = None
    parameters['dayLength'] = float(top.entries[13])
    gen()
    '''except:
        tkMessageBox.showwarning("Warning!","Unfilled Parameters!")'''

def but4Press():
    top.Entry1.delete(0,END)
    top.Entry2.delete(0,END)
    top.Entry3.delete(0,END)
    top.Entry4.delete(0,END)
    top.Entry5.delete(0,END)
    top.Entry6.delete(0,END)
    top.Entry7.delete(0,END)
    top.Entry8.delete(0,END)
    top.Entry9.delete(0,END)
    top.Entry10.delete(0,END)
    top.Entry11.delete(0,END)
    top.Entry12.delete(0,END)
    top.Entry13.delete(0,END)
    top.Entry14.delete(0,END)

def but5Press():
    global mod
    if mod == 1:
        top.Button5.configure(image=image2)
        mod = 2
    elif mod == 2:
        top.Button5.configure(image=image1)
        mod = 1

def but6Press():
    from fomite_ABM_econGUI import vp_start_econgui
    vp_start_econgui(top)

def but7Press():
    #polynomial interpolation lagrange
    from Numericals import lagrange_interpolation
    from matplotlib.pylab import arange
    try:
        discretization_range = arange(0,days-1,.01)
        incubating_out = []
        symptomatic_out = []
        xvals = [x[-1] for x in complete_output]
        inyvals = [x[2] for x in complete_output]
        symyvals = [x[3] for x in complete_output]
        conyvals = [x[4] for x in complete_output]
        incubating_out = lagrange_interpolation(discretization_range, xvals, inyvals)
        symptomatic_out = lagrange_interpolation(discretization_range, xvals, symyvals)
        contamination_out = lagrange_interpolation(discretization_range, xvals, conyvals)

        print(xvals)
        print(incubating_out)
        global image1, image2, mod
        pl.clf()

        pl.plot(discretization_range,symptomatic_out,label='Symptomatic')
        pl.plot(discretization_range,incubating_out,label='Incubating')
        pl.legend()
        pl.ylabel('Population')
        pl.xlabel('Days')
        pl.savefig('fig1')
        pl.plot(discretization_range,contamination_out, label=None)
        pl.ylabel('Fomite contamination')
        pl.xlabel('Days')
        pl.legend().remove()
        pl.savefig('fig2')
        pl.clf()

        img = Image.open('fig1.png')
        img = img.resize((587,486), PIL.Image.ANTIALIAS)
        img.save('fig1.png')

        img = Image.open('fig2.png')
        img = img.resize((587,486), PIL.Image.ANTIALIAS)
        img.save('fig2.png')

        image1 = ImageTk.PhotoImage(file='fig1.png')
        image2 = ImageTk.PhotoImage(file='fig2.png')
        mod = 1

        top.Button5.configure(image=image1)
    except:
        tkMessageBox.showwarning("Warning!","No Curve to Interpolate!")

def but8Press():
    print('gangnam style')
    #retrieve TSV and integrate to model
    name = tkFileDialog.askopenfilename()
    from sickchildcare_parser import cases_to_agents
    agents = cases_to_agents(name, 'all', 'e', 5)
    print(agents)
    for i in agents:
        print(i.data)

def gen():
    from fomite_ABM import Agent, Fomite

    ### A bunch of crap to test run the model
    agentList = []
    fomite = Fomite(id='1f')
    nAgents = agents
    for i in range(nAgents):
        agentList.append(Agent(id=i))
    agentList[1].state = 3
    #agentList[1].recoveryTime = 7
    agentList[1].contamination = 500
    ## This matrix assumes one fomite that everybody touches
    G = nx.complete_graph(nAgents)
    #print G.edges()
    nx.set_node_attributes(G,'bipartite',1)
    G.add_node(fomite.id,bipartite=0)

    for i in range(nAgents):
        G.add_edge(i,'1f')

    #print G.neighbors(1)
    #param = parameters.values()
    #print('param', len(param))
    print(parameters)
    print(days)
    print(agents)
    param = copy.deepcopy(parameters)
    #print globals()
    #reformatted parameters as dictionary for retrieval
    #GUI generation

    ### parallelized multiple runs
    '''
    servers = ('local',)
    jobServer = pp.Server(ppservers=servers)
    print 'active nodes', jobServer.get_active_nodes()
    mList = [Model(copy.deepcopy(agentList),[copy.deepcopy(fomite)],28,G,param) for i in range(200)]

    output = []
    start = time.time()
    jobs = [jobServer.submit(run_model,args=(m,),modules=('numpy as np','networkx as nx','random as pr')) for m in mList]
    for job in jobs:
        output.append(job())
    print 'time elapsed', time.time()-start

    output = np.array(output)
    avgOutput = np.mean(output,axis=0)
    stdOutput = np.std(output,axis=0)

    upperBound = avgOutput + stdOutput
    lowerBound = avgOutput - stdOutput
    days = avgOutput[:,-1]
    pl.plot(days,avgOutput[:,3],'b',lw=4,label='Symptomatic')
    pl.fill_between(days,lowerBound[:,3],upperBound[:,3],facecolor='b',lw=0,alpha=0.5)
    pl.plot(days,avgOutput[:,2],'g',lw=4,label='Incubating')
    pl.fill_between(days,lowerBound[:,2],upperBound[:,2],facecolor='g',lw=0,alpha=0.5)
    pl.legend(loc=0)
    pl.ylabel('Symptomatic')
    pl.xlabel('Days')
    pl.ylim(ymin=0)
    pl.figure()
    pl.plot(days,avgOutput[:,4],color='r',lw=4)
    pl.fill_between(days,lowerBound[:,4],upperBound[:,4],facecolor='r',lw=0,alpha=0.5)
    pl.ylabel('Fomite contamination')
    pl.xlabel('Days')
    pl.ylim(ymin=0)
    pl.show()
    '''

    m = Model(agentList,[fomite,],days,G,param)
    #print m.contactPairs.edges()

    m.run()

    global complete_output
    complete_output = m.output
    #safe copy by value NOT reference
    top._set_out(complete_output, agentList)
    out = np.array(complete_output)
    #print out[:,2]

    pl.plot(out[:,-1],out[:,3],label='Symptomatic')
    pl.plot(out[:,-1],out[:,2],label='Incubating')
    pl.legend()
    pl.ylabel('Population')
    pl.xlabel('Days')
    pl.savefig('fig1')
    pl.plot(out[:,-1],out[:,4], label=None)
    pl.ylabel('Fomite contamination')
    pl.xlabel('Days')
    pl.legend().remove()
    pl.savefig('fig2')
    pl.clf()

    global image1
    global image2
    global mod

    mod = 1

    img = Image.open('fig1.png')
    img = img.resize((587,486), PIL.Image.ANTIALIAS)
    img.save('fig1.png')

    img = Image.open('fig2.png')
    img = img.resize((587,486), PIL.Image.ANTIALIAS)
    img.save('fig2.png')

    image1 = ImageTk.PhotoImage(file='fig1.png')
    image2 = ImageTk.PhotoImage(file='fig2.png')
    top.Button5.configure(image=image1)

    #print 'fomite contamination', m.fomite.contamination
    #for a in m.agentList:
    #    print 'state', a.state
    #    print 'contamination', a.contamination
    #for a in m.agentList:
    #    print a.neighbors

if __name__ == '__main__':
    vp_start_gui()


import networkx as nx
from networkx.algorithms import isomorphism
import argparse
import pickle
from tqdm import tqdm
"""get nx graphs from remapped_fp_file"""
def get_single_subgraph_nx(frequent_subgraph_lines):
    '''
        create graph from gSpan data format
    '''
    graph_id = frequent_subgraph_lines[0].strip().split(' ')[2]
    support = frequent_subgraph_lines[0].strip().split(' ')[4]
    graph_nx = nx.DiGraph(name = graph_id)

    for line in frequent_subgraph_lines[1:]:
        if line.startswith('v'):
            parsed_line = line.strip().split(' ')
            node_id = parsed_line[1]
            node_type = parsed_line[2]
            graph_nx.add_node(node_id,type = node_type)

        elif line.startswith('e'):
            parsed_line = line.strip().split(' ')
            node_from = parsed_line[1]
            node_to = parsed_line[2]
            edge_type = parsed_line[3]
            graph_nx.add_edge(node_from,node_to,type=edge_type)

    return graph_nx

def get_subgraphs_nx(remapped_fp_file):
    fsg_lines_list = []
    fsg_lines = []
    with open(remapped_fp_file) as f:
        for line in f:
            if line == '\n' and fsg_lines != []:
                fsg_lines_list.append(fsg_lines)
                fsg_lines = []
            else:
                fsg_lines.append(line)

    nx_subgraphs = []
    for fsg_ls in fsg_lines_list:
        nx_subgraphs.append(get_single_subgraph_nx(fsg_ls))

    return nx_subgraphs

"""set up node matcher and edge matcher"""
NODE_MATCHER_FUNC = isomorphism.categorical_node_match("type",None)
EDGE_MATCHER_FUNC = isomorphism.categorical_edge_match("type",None)

def is_subgraph(g,G):
    '''check if g is a subgraph of G'''
    dgmather = isomorphism.DiGraphMatcher(G,g,node_match = NODE_MATCHER_FUNC, edge_match = EDGE_MATCHER_FUNC)
    if dgmather.subgraph_is_isomorphic():
        return True
    else:
        return False

def sort_nx_graphs(nx_graphs, order = 'increasing'):
    if order == 'increasing':
        return sorted(nx_graphs, key = lambda g: g.number_of_nodes())
    elif order == 'decreasing':
        return sorted(nx_graphs, key = lambda g: g.number_of_nodes(), reverse = True)
    else:
        raise NotImplementedError

def filter_mined_nx_subgraphs(nx_subgraphs, save_path = None):
    '''filter out mined subgraphs by which is a subgrpah in other mined subgraphs'''
    sorted_nx_graphs = sort_nx_graphs(nx_subgraphs, order = 'increasing')
    filtered_nx_graphs = []

    for i in tqdm(range(len(sorted_nx_graphs)-1)):
        g = sorted_nx_graphs[i]
        filtered_nx_graphs.append(g)
        for j in range(i+1,len(sorted_nx_graphs)):
            G = sorted_nx_graphs[j]
            if is_subgraph(g,G):
                filtered_nx_graphs.pop()
                break
    if save_path is not None:
        write_graphs(filtered_nx_graphs, save_path)
        print('write graphs to :', save_path)

    return filtered_nx_graphs

def write_graphs(nx_subgraphs, output_pickle_path):
    # Dump List of graphs
    with open(output_pickle_path, 'wb') as f:
        pickle.dump(nx_subgraphs, f)

def load_graphs(input_pickle_path):
    # Load List of graphs
    with open(input_pickle_path, 'rb') as f:
        return pickle.load(f)

'''arg parser'''

if __name__ == "__main__":
    # parser = argparse.ArgumentParser(description='filter mined subgraphs')
    parser.add_argument('-i', '--input_fp_file', help='input remapped fp file path', required=True)
    parser.add_argument('-o', '--output_path', help='write filtered graphs in pickle format', required=False, default = "")

    args = vars(parser.parse_args())

    remapped_fp_path = args['input_fp_file']
    save_path = args['output_path']

    '''usage'''

    nx_subgraphs = get_subgraphs_nx(remapped_fp_path)
    print('original frequent subgraph number: ', len(nx_subgraphs))
    filtered_nx_subgraphs = filter_mined_nx_subgraphs(nx_subgraphs)
    print('filtered frequent subgraph number: ', len(filtered_nx_subgraphs))

    if save_path != "":
        write_graphs(filtered_nx_subgraphs,save_path)

    # load graphs
        # loaded_graphs = load_graphs('/shared/nas/data/m1/wangz3/schema_composition/Schema_Composition/gSpan_official/gSpan6/test_save.pickle')
        # print(isinstance(loaded_graphs,list))
        # print(len(loaded_graphs))
        # print(loaded_graphs[0].nodes.data())


#!/usr/bin/python3
import images
import os
import time
import random

# Replace RPG starter project with this code when new instructions are live
images.title()
time.sleep(5)
os.system("clear")

steel_count = 0
iron_count = 0
tin_count = 0
pewter_count = 0

def showInstructions():
    # print a main menu and the commands
    print('''
Mistborn (A Brandon Sanderson fan-fiction Text-Based RPG)
========
Commands:
  go [direction]
  get [item]
  burn [metal that was ingested]: one word command
  push [if steel burned]
  pull [if iron burned]
  boost [if pewter burned]: one word command
  drink [from an item]
  back [to go back to previous room]
''')

def backstory():
    print("""For a thousand years the ash fell and no flowers bloomed. For a thousand years the Skaa slaved in misery and lived in fear. For a thousand years the Lord Ruler, the "Sliver of Infinity," reigned with absolute power and ultimate terror, divinely invincible. Then, when hope was so long lost that not even its memory remained, a terribly scarred, heart-broken half-Skaa rediscovered it in the depths of the Lord Ruler's most hellish prison. Kelsier "snapped" and found in himself the powers of a Mistborn. A brilliant thief and natural leader, he turned his talents to the ultimate caper, with the Lord Ruler himself as the mark.

Kelsier recruited the underworld's elite, the smartest and most trustworthy allomancers, each of whom shares one of his many powers, and all of whom relish a high-stakes challenge. Only then does he reveal his ultimate dream, not just the greatest heist in history, but the downfall of the divine despot.

But even with the best criminal crew ever assembled, Kel's plan looks more like the ultimate long shot, until luck brings a ragged girl named Vin into his life.

You are Vin, and find yourself locked away after a mission gone horribly wrong. You wake up in a cell.

"I need to get out."
""")

    input("Press Enter to continue...")

def showStatus():
    # print the player's current status
    print('---------------------------')
    print('You are in the ' + currentRoom)
    print(rooms[currentRoom]['description'])
    # print the current inventory
    print('Inventory : ' + str(inventory))
    # print an item if there is one
    if "item" in rooms[currentRoom]:
        print('You see a ' + rooms[currentRoom]['item'])
    print("Type help if you need instructions again.")
    print("---------------------------")

# an inventory, which is initially empty
inventory = []
metals = ['steel', 'iron', 'pewter']
# a dictionary linking a room to other rooms
# A dictionary linking a room to other rooms
rooms = {

    'Cell': {
        'description': 'Thick steel bars block your exit to the south.\nThrough the bars is a sleeping guard and beyond him is a staircase leading up.\nIn your cell is a bucket to do your business in, and a straw mat.\nStarving you might be on your captor\'s agenda but they did leave you a cup of water.',
        'exits': {
            'south': 'Guard\'s Room'},
        'item': 'cup',
        'locked': True,
        'metal': 'bars',
        'clear': True
    },
    'Guard\'s Room': {
        'description': 'A simple desk for a guard to set his dinner, stairs leading up, and the guard occupy the room.\n A key ring hangs on the guard\'s belt.',
        'exits': {
            'north': 'Cell',
            'up': 'Stairs'
        },
        'person': 'guard',
        'item': 'keys',
        'metal': 'keys',
        'locked': False,
        'clear': False
    },
    'Stairs': {
        'description': 'A single guard carries a tray of food down the stairs, and you catch them unaware.\nA bag hangs from the belt of the guard. \nYou need to keep going up.',
        'exits': {
            'up': 'Hall',
            'down': 'Guard\'s Room'},

        'item': 'coins',
        'person': 'guard',
        'metal': 'coins',
        'clear': False,
        'locked': False,
    },
    'Hall': {
        'description': 'An empty hallway running east to west.\n You see bright lights illuminating the end of the hall to the east.\nThe west is dimly lit by slow burning candles.\n With two guards taken care of below, you are aware it\'s not going to be easy to escape.',
        'exits': {
            'east': 'Grand Hall',
            'west': 'Guard Tower',
            'down': 'Stairs'
        },
        'clear': True,
        'locked': False
    },
    'Grand Hall': {
        'description': 'A gleaming crystal chandelier hangs in the middle of the Grand Hall, but that is not the first thing you notice.\n50 of the top noblemen and women of Luthadel and surrounding Scadriel cities.\nBarring the doors to the keep are four Obligators, spikes piercing their eyes, and yes, they notice you.',
        'death': 'obligator',
        'clear': False,
        'locked': False,
    },
    'Guard Tower': {
        'description': 'A wooden door blocks the way into the tower.\nIf I can get to a window up high, I can escape.',
        'exits': {
            'up': 'Landing',
            'east': 'Hall'},
        'clear': True,
        'locked': True
    },
    'Landing': {
        'description': 'Halfway up the tower a door opens up to a landing. \nThe room\'s furniture is arranged in an office style and at a desk is large, bald beast of a man. He looks up in shock. Clearly he was not expecting you to be out of your cell. He calls over to you as he readies himself to subdue you. "You should have stayed in the cell.\nNow, the pain you feel will leave you wishing you were dead. When I\'m through with you, the Obligators downstairs will be happy to take you to the Ministry of Steel. \nThey\'ll start with spikes driven through your wrists, and then work their way up.\n\nNow! Feel the pain, you little half-breed!"',
        'exits': {
            'up': 'Tower Window',
            'down': 'Landing'},
        'metal': 'vial',
        'item': 'vial',
        'person': 'Captain of the Guard',
        'clear': False
    },
    'Tower Window': {
        'description': 'The city of Luthadel sprawls outward with torches illuminating the street corners and the mists crawling to fill the night air.',
        'clear': True

    }
}

# start the player in the Hall
currentRoom = 'Cell'
previousRoom = ''
backstory()
showInstructions()

# loop forever
while True:

    showStatus()

    # get the player's next 'move'
    # .split() breaks it up into an list array
    # eg typing 'go east' would give the list:
    # ['go','east']
    move = ''
    while move == '':
        move = input('>')

    # split allows an items to have a space on them
    # get golden key is returned ["get", "golden key"]
    move = move.lower().split(" ", 1)
    os.system('clear')

    if move[0] == "back":
        # If the previous room is not empty, go back to the previous room
        if previousRoom:
            currentRoom, previousRoom = previousRoom, currentRoom
            print(f"You go back to {currentRoom}")
        # Otherwise, print an error message and stay in the current room
        else:
            print("You can't go back any further")
    # Check if the player wants to move to a new room
    if move[0] == 'go':
        # check that they are allowed wherever they want to go
        if 'person' in rooms[currentRoom] and not rooms[currentRoom]['clear']:
            print(
                f"The {rooms[currentRoom]['person']} in the {currentRoom} will not let you get by so easily.")
        else:
            if 'locked' in rooms[currentRoom] and rooms[currentRoom]['locked'] == True:
                print(f"The door is locked. You must find another way or find a key.")
                if 'keys' in inventory:
                        print("You use the keys to unlock the door.")
                        rooms[currentRoom]['locked'] = False

                # not removing keys because they can be used as a weapon.
                else:
                     print("You do not have the keys. But that won't hold you back for long. Kelsier said even the water we drink has trace metals that might be worth burning.")

            elif len(move) > 1 and move[1] in rooms[currentRoom]["exits"]:
                currentRoom = rooms[currentRoom]["exits"][move[1]]
            else:
                print("You can't go that way!")

    # if they type 'get' first
    if move[0] == 'get':
        # if the room contains an item, and the item is the one they want to get
        # otherwise, if the item isn't there to get
        if rooms[currentRoom]['clear'] == False:
            print(
                f"The {rooms[currentRoom]['person']} in the {currentRoom} will not let you get the {rooms[currentRoom]['item']} so easily")

        elif "item" in rooms[currentRoom] and move[1] in rooms[currentRoom]['item']:
            # add the item to their inventory
            inventory += [move[1]]
            # display a helpful message
            print(move[1] + ' taken!')
            # delete the item from the room
            del rooms[currentRoom]['item']
        else:
            # tell them they can't get it
            print('Can\'t get ' + move[1] + '!')
    # if user forgets the commands
    if move[0] == 'help':
        showInstructions()

    if move[0] == 'drink':

        if 'cup' in inventory:
            inventory.remove('cup')
            inventory += metals
            print("You sense a pool of power within.")
        elif 'vial' in inventory:
            inventory.remove('vial')
            inventory += metals
            print("You sense a pool of power within.")
        else:
            print("You don\'t have anything to drink!")

    if move[0] == 'burn':
        metalchoice = input("Which metal will you burn?\n")

        if 'steel' in inventory and metalchoice == 'steel':
            print("You can feel that the metal around pulses, and blue lines shoot out from you to each metal object in the room. You can now push metal away from you.")
            steel_count = 3
            print(
                f"Blue lines extend to objects in the room. You can push the {rooms[currentRoom]['metal']}.")
        elif 'iron' in inventory and metalchoice == 'iron':
            print("You can feel that the metal around pulses, and blue lines shoot out from you to each metal object in the room. You can now pull metal to you.")
            iron_count = 3
            print(
                f"Blue lines extend to objects in the room. You can pull the {rooms[currentRoom]['metal']}.")
        elif 'pewter' in inventory and metalchoice == 'pewter':
            print("You feel your body tighten with strength. You feel like you can take a hit from a hammer, break bones with your bare hands, or balance atop a lightpost. You can now boost your physical prowess.")
            pewter_count = 3
        # Tin is not useful in my scenario so I'm removing it. Could be used in future iterations if more stealth is desired.
        # elif metalchoice == 'tin':
        #     print(
        #         "Your senses heighten. You can hear, see, smell, taste, and feel beyond even the most adept.")
        #     tin_count = 3
        else:
            print("You have not ingested any metals. Find some. Your fate depends on it!")
    # Allomancy actions
    if move[0] == 'push':
        steel_count - 1
        if 'coins' in inventory and move[1] and steel_count > 0:
            print(
                f"A nifty little Kelsier taught you. You push the {move[1]} with ferocious velocity. The {rooms[currentRoom]['person']} is torn to shreds.")
            rooms[currentRoom]['clear'] = True
            rooms[currentRoom]['item'] = move[1]
            rooms[currentRoom]['description'] = 'Any threats have been neutralized. You need to move before anyone checks this room.'
            inventory.remove('coins')
        elif 'keys' in inventory and move[1] and steel_count > 0:
            bodypart = ['head', 'chest', 'leg', 'throat']
            randpart = random.choice(bodypart)
            print(
                f" The keys blur with such speed they cut through any living thing. The {rooms[currentRoom]['person']} has key-sized hole through their {randpart}.")
            rooms[currentRoom]['clear'] = True
            inventory.remove('keys')
            rooms[currentRoom]['item'] = move[1]
            rooms[currentRoom]['description'] = 'Any threats have been neutralized. You need to move before anyone checks this room.'
        elif 'metal' in rooms[currentRoom] and move[0] == 'push' and steel_count > 0:
            print(
                f"Blue lines illuminate {rooms[currentRoom]['metal']}. You push! The {rooms[currentRoom]['metal']} bursts forward and sends you back into the wall behind you.")
            if rooms[currentRoom]['locked'] == True and rooms[currentRoom]['metal'] == 'bars':
                rooms[currentRoom]['locked'] = False
                print(
                    "You have created your own key. The guard wakes with a start and lunges toward you.")
            elif 'exits' in rooms[currentRoom] and move[1] in rooms[currentRoom]['exits']:
                previousRoom = currentRoom
                currentRoom = rooms[currentRoom]['exits'][move[1]]
                print(f"You enter the {currentRoom}.")
            else:
                print("You can't go that way!")
        else:
            print("You need more steel. Find some!\n(You might try to burn the metal if you have it in your inventory.)")
    if move[0] == 'pull':
        iron_count - 1
        if 'coins' in rooms[currentRoom] and move[1] and iron_count > 0:
            print(
                f"You pull the bag of coins to your hand. These might be useful.")
            inventory += ['item']['coins']
            del rooms[currentRoom]['item']
        elif 'metal' in rooms[currentRoom] and move[0] == 'pull' and iron_count > 0:
            if rooms[currentRoom]['metal'] == rooms[currentRoom]['item']:
                print(
                    f"You pocket the {rooms[currentRoom]['item']}, and think of devious ways to use it.")
                inventory.append(rooms[currentRoom]['item'])
                del rooms[currentRoom]['item']
            elif rooms[currentRoom]['locked'] == True and rooms[currentRoom]['metal'] == 'bars':
                rooms[currentRoom]['locked'] = False
                print(
                    f"Blue lines illuminate {rooms[currentRoom]['metal']}. You pull! The {rooms[currentRoom]['metal']} breaks free of the hinges and comes straight toward you You dodge just in time, and raise a clatter.")
                print(
                    "You have created your own key. The guard wakes with a start and lunges toward you.")
            elif 'exits' in rooms[currentRoom] and move[1] in rooms[currentRoom]['exits']:
                previousRoom = currentRoom
                currentRoom = rooms[currentRoom]['exits'][move[1]]
                print(f"You enter the {currentRoom}.")
            else:
                print("You can't go that way!")
            # Trying to pull multiple metals to you.
            # if rooms[currentRoom]['metal'] == move[1]:
            #     print(f"You pull {move[1]} to you.")
            #     if rooms[currentRoom]['metal'] == 'belt buckle':
            #         print(
            #             f"The rooms {[currentRoom]['person']}'s pants drop to their ankles, giving you a laugh.")
            #     elif rooms[currentRoom]['metal'] == 'dagger' or 'spear':
            #         print(
            #             f"You take the rooms{[currentRoom]['person']}'s crude weapon. You toss it aside and laugh at their look of utter defeat.")
        else:
            print("You need more iron. Find some!\n(You might try to burn the metal if you have it in your inventory.)")
    if move[0] == 'boost':
        pewter_count - 1
        if 'person' in rooms[currentRoom] and pewter_count > 0:
            get_wrecked = ['jugular', 'skull', 'limbs']
            pewterdeath = random.choice(get_wrecked)
            rooms[currentRoom]['clear'] = True
            rooms[currentRoom]['description'] = 'Any threats have been neutralized. You need to move before anyone checks this room.'
            if pewterdeath == 'jugular':
                print(
                    f" The {rooms[currentRoom]['person']} gasps when they see the 'little girl' in front of them shirk off any blows that would have maimed any average person.\n You laugh under your breath and send a quick jab to their throat, causing them to splutter, gasping for their last breaths.")
            elif pewterdeath == 'skull':
                print(
                    f" You flip over the {rooms[currentRoom]['person']} and smashing their skull with a pewter enhanced fist.\n Good night, tough guy.")
            else:
                print(
                    f"A series of blows from kicks and jabs to the {rooms[currentRoom]['person']} limbs leave them broken but still breathing.\n You slap the {rooms[currentRoom]['person']} which put them to sleep. Life is more than they deserve.")

        else:
            print("You need more pewter. Find some!\n(You might try to burn the metal if you have it in your inventory.)")

    # Define how a player can win
    if currentRoom == 'Tower Window' and 'steel' in inventory and 'coins' in inventory:
        print('You leap out of the window, like Kelsier taught you, tossing a coin down below. You push off the coin, sending you skyward, and soar out into the mists... YOU WIN!')
        images.ending()
        break
    elif currentRoom == 'Tower Window' and 'steel' in inventory and 'keys' in inventory:
        print('You leap out of the window, like Kelsier taught you, tossing the cell\'s keys towards the cobblestone streets below. Keys were indeed a means to escape. You trace the blue lines in your sight and steel push out into the mists... YOU WIN!')
        images.ending()
        break

    # If a player enters a room with a obligators
    elif rooms.get(currentRoom, {}).get('death') == 'obligator':
        print('An Obligator found you and easily detains you. You are but a flea compared to the Lord Ruler and his Obligators... GAME OVER!')
        images.obligator()
        break

print("If you enjoyed the story so far, check out the series Mistborn by Brandon Sanderson.")


pkgname = "libice"
pkgver = "1.1.1"
pkgrel = 0
build_style = "gnu_configure"
hostmakedepends = [
    "pkgconf",
    "automake",
    "libtool",
    "xorg-util-macros",
    "xtrans",
]
makedepends = ["xorgproto", "xtrans"]
pkgdesc = "Inter Client Exchange (ICE) library for X"
maintainer = "q66 <q66@chimera-linux.org>"
license = "MIT"
url = "https://xorg.freedesktop.org"
source = f"$(XORG_SITE)/lib/libICE-{pkgver}.tar.gz"
sha256 = "04fbd34a11ba08b9df2e3cdb2055c2e3c1c51b3257f683d7fcf42dabcf8e1210"

def post_install(self):
    self.install_license("COPYING")

@subpackage("libice-devel")
def _devel(self):
    return self.default_devel()


from base import VisBase
from helper import get_heat_map
import os
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import torch
import torch.nn.functional as F
import math
import numpy as np
import matplotlib as mpl
from mpl_toolkits.axes_grid1 import make_axes_locatable
from mpl_toolkits.axes_grid1 import ImageGrid

VIS_ROOT = os.path.dirname(os.path.realpath(__file__))

class ProjVis(VisBase):
    def __init__(self,
                 exp,
                 **kwargs):
        super(ProjVis, self).__init__(exp, **kwargs)
        self.save_each = False
        self.show = True
        self.batch_id = 0
        self.target_id = 0
        self.center_tf = (23, 23)
        self.rect_color = 'yellow'

    def center_scan(self):
        half_width = 21
        half_height = 21
        max_t = 250
        max_f = 128

        t_grid = np.linspace(half_width + 2, max_t - half_width - 2, num=6)
        f_grid = np.linspace(half_height + 2, max_f - half_height - 2, num=5)

        center_list = []
        for t in t_grid:
            for f in f_grid:
                center_tf = (int(t), int(f))
                center_list.append(center_tf)
        return center_list

    def fig_structure_grid(self):
        fig = plt.figure(figsize=(7, 1.5))
        grid = ImageGrid(fig, 111,
                         nrows_ncols=(1, 5),
                         axes_pad=0.07,
                         share_all=True,
                         cbar_mode='single',
                         label_mode='L')
        im1 = self.fig_spec(ax=grid[0])
        im2 = self.fig_entropy_softmax(ax=grid[1])
        im3 = self.fig_pos_entropy_softmax(ax=grid[2])
        im4 = self.fig_entropy_sparsemax(ax=grid[3])
        im5 = self.fig_pos_entropy_sparsemax(ax=grid[4])

        max_val = im4.get_array().max()
        min_val = im4.get_array().min()
        if max_val > 0.2 and max_val - min_val > 0.1:
            max_val = round(max_val - 0.1, 1)
            min_val = round(min_val, 1)
            plt.colorbar(im4, cax=grid.cbar_axes[0], ticks=[min_val, max_val])
            grid.cbar_axes[0].set_yticklabels([min_val, str(max_val)])
        else:
            plt.colorbar(im3, cax=grid.cbar_axes[0])

        # plt.colorbar(im3, cax=grid.cbar_axes[0])

        fontsz = 12
        grid[0].set_xlabel('(a) spectrogram', fontsize=fontsz, labelpad=6.2)
        grid[1].set_xlabel(r'(b) $\tilde{\mathbf{h}}$', fontsize=fontsz)
        grid[2].set_xlabel(r'(c) $\tilde{\mathbf{h}}^\dag$', fontsize=fontsz)
        grid[3].set_xlabel(r'(d) $\bar{\mathbf{h}}$', fontsize=fontsz)
        grid[4].set_xlabel(r'(e) $\bar{\mathbf{h}}^\dag$', fontsize=fontsz)

        grid[0].get_xaxis().set_ticks([])

        if self.show:
            # fig.suptitle('{}_structure_grid_b{}.png'.format(self.label, str(self.batch_id)))
            plt.show()
        else:
            fig.savefig('{}/{}/{}_structure.png'.format(VIS_ROOT, self.label, self.label))

    def fig_relation_grid(self, suffix=None):
        fig = plt.figure(figsize=(4.8, 1.8))
        grid = ImageGrid(fig, 111,
                         nrows_ncols=(1, 3),
                         axes_pad=0.07,
                         share_all=True,
                         cbar_mode='single',
                         label_mode='L'
                         )
        self.fig_spec_rect(ax=grid[0])
        self.fig_spec_rect(ax=grid[0])
        im1 = self.fig_relation(ax=grid[1])
        im2 = self.fig_pos_relation(ax=grid[2])

        fontsz = 12
        grid[0].set_xlabel('(a) spectrogram', fontsize=fontsz)
        grid[1].set_xlabel(r'(b) $\mathbf{E}_i$', fontsize=fontsz)
        grid[2].set_xlabel(r'(c) $\mathbf{E}_i^{\dag}$', fontsize=fontsz)
        grid[0].get_xaxis().set_ticks([])

        if im1.get_array().max() == 0. and im2.get_array().max() == 0.:
            import matplotlib.colors
            norm = matplotlib.colors.Normalize(vmax=1., vmin=0.)
            plt.colorbar(matplotlib.cm.ScalarMappable(norm=norm, cmap='jet'), cax=grid.cbar_axes[0])

        elif im1.get_array().max() == 0.:
            plt.colorbar(im2, cax=grid.cbar_axes[0])
        elif im2.get_array().max() == 0.:
            plt.colorbar(im1, cax=grid.cbar_axes[0])
        else:
            plt.colorbar(im1, cax=grid.cbar_axes[0])

        if self.show:
            # fig.suptitle('{}_relation_grid_b{}_{}.png'.format(self.label, self.batch_id, str(self.center_tf)))
            plt.show()
        else:
            if suffix is not None:
                fig.savefig('{}/{}/{}_relation_grid_{}.png'.format(VIS_ROOT,
                                                                   self.label,
                                                                   self.label,
                                                                   str(suffix)))
            else:
                fig.savefig('{}/{}/{}_relation_grid.png'.format(VIS_ROOT,
                                                                self.label,
                                                                self.label))

    def fig_spec(self, ax=None):
        if not ax:
            fig, ax = plt.subplots()
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)

        self.plot_spec(ax=ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_spec.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()

    def fig_spec_rect(self, ax=None):
        if not ax:
            fig, ax = plt.subplots()
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)

        self.plot_spec_rect(ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_spec_rect.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()

    def fig_relation(self, ax=None):
        self.reload(exp="esc-folds-rblock",
                    r_structure_type="zero", softmax_type="softmax")
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)
        if not ax:
            fig, ax = plt.subplots()
        im = self.plot_relation_heatmap(ax=ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_relation.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()
        return im

    def fig_pos_relation(self, ax=None):
        self.reload(exp="esc-folds-rblock-pe",
                    r_structure_type="zero", softmax_type="softmax")
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)
        if not ax:
            fig, ax = plt.subplots()
        im = self.plot_relation_heatmap(ax=ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_pos_relation.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()
        return im

    def fig_entropy_softmax(self, ax=None):
        self.reload(exp="esc-folds-rblock",
                    r_structure_type="minus_entropy", softmax_type="softmax")
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)
        if not ax:
            fig, ax = plt.subplots()
        im = self.plot_structure_feat(ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_entropy_softmax.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()

        return im

    def fig_entropy_sparsemax(self, ax=None):
        self.reload(exp="esc-folds-rblock",
                    r_structure_type="minus_entropy", softmax_type="sparsemax")
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)
        if not ax:
            fig, ax = plt.subplots()
        im = self.plot_structure_feat(ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_entropy_sparsemax.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()
        return im

    def fig_pos_entropy_softmax(self, ax=None):
        self.reload(exp="esc-folds-rblock-pe",
                    r_structure_type="minus_entropy", softmax_type="softmax")
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)
        if not ax:
            fig, ax = plt.subplots()
        im = self.plot_structure_feat(ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_pos_entropy_softmax.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()

        return im

    def fig_pos_entropy_sparsemax(self, ax=None):
        self.reload(exp="esc-folds-rblock-pe",
                    r_structure_type="minus_entropy", softmax_type="sparsemax")
        self.feed(batch_id=self.batch_id, data_id=0, target_id=self.target_id)

        folder = '{}/{}'.format(VIS_ROOT, self.label)
        if not os.path.exists(folder):
            os.makedirs(folder)
        if not ax:
            fig, ax = plt.subplots()
        im = self.plot_structure_feat(ax)
        if self.save_each:
            fig.savefig('{}/{}/{}_pos_entropy_sparsemax.png'.format(VIS_ROOT, self.label, self.label))
        else:
            pass
            # plt.show()

        return im

    def plot_spec(self, ax):
        ax.imshow(self.spec, cmap='magma', origin='lower')

    def plot_spec_rect(self, ax):
        ax.imshow(self.spec, cmap='magma', origin='lower')
        self.plot_rect(ax)

    def plot_rect(self, ax, text=None):
        width = 43
        height = 43
        lower_left = (self.center_tf[0] - math.floor(width / 2), self.center_tf[1] - math.floor(height / 2))

        rect = Rectangle(xy=lower_left, width=width, height=height, linewidth=1,
                         edgecolor=self.rect_color, facecolor='none')
        ax.add_patch(rect)
        # ax.scatter(self.center_tf[0], self.center_tf[1], s=10,  marker='x', c=self.rect_color)
        if text == 'p':
            ax.text(self.center_tf[0] - 10, self.center_tf[1] - 8, r'$p$', fontsize=10, color=self.rect_color)
        elif text == 'q':
            ax.text(self.center_tf[0] - 10, self.center_tf[1] - 8, r'$q$', fontsize=10, color=self.rect_color)

    def plot_relation_heatmap(self, ax, fig=None, alpha=1.):
        fsz, tsz = self.spec.shape
        heat_map = get_heat_map(self.spec, nl_map=self.nl_map, center_tf=self.center_tf)

        # (F, T)
        heat_map = F.interpolate(torch.from_numpy(heat_map),
                                 size=(fsz, tsz),
                                 mode='bicubic').squeeze()

        heat_map = heat_map.clamp_(min=0.).numpy()

        # alpha, multiply heat_map by alpha
        im = ax.imshow(heat_map, cmap='jet', alpha=alpha, origin='lower')
        self.plot_rect(ax)

        return im

    def plot_structure_feat(self, ax, fig=None, alpha=1.):

        fsz, tsz = self.spec.shape
        structure_feat = F.interpolate(torch.from_numpy(self.relation_feat),
                                       size=(fsz, tsz),
                                       mode='bicubic').squeeze()

        structure_feat.clamp_(min=0., max=1.)

        structure_feat = structure_feat.numpy()

        # alpha, multiply heat_map by alpha
        im = ax.imshow(structure_feat, cmap='bwr', origin='lower', alpha=alpha)

        return im

    def add_colorbar(self, ax):
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)

        plt.colorbar(cax=cax)

def plot_relation(vis):
    vis.batch_id = 0

    for l in range(50):
        vis.target_id = l
        for i, center_tf in enumerate(vis.center_scan()):
            vis.center_tf = center_tf
            vis.fig_relation_grid(suffix=i)
        audio_path = "{}/{}/{}.wav".format(VIS_ROOT, vis.label, vis.label)
        vis.save_audio(wav_path=audio_path)

def plot_structure(vis):
    vis.batch_id = 0
    # vis.target_id = 47
    # vis.fig_structure_grid()
    for l in range(50):
        vis.target_id = l
        vis.fig_structure_grid()

if __name__ == '__main__':
    os.environ["CUDA_VISIBLE_DEVICES"] = "1"
    vis = ProjVis(exp="esc-folds-rblock",
                  ckpt_prefix="Run029")
    plt.rcParams['figure.dpi'] = 300
    plt.rcParams['text.usetex'] = True
    plt.rc('font', family='Times Roman')
    vis.show = False
    plot_relation(vis)
    plot_structure(vis)

    # vis.target_id = 23
    # for i, center_tf in enumerate(vis.center_scan()):
    #     # if i != 6:
    #     #     continue
    #     vis.center_tf = center_tf
    #     vis.fig_relation_grid(suffix=i)
    #     # break


from datetime import datetime, timedelta
from functools import reduce
from django import db
from django.conf import settings
from django.db import models
from django.db.models import Sum
from django.contrib.auth import get_user_model
from jalali_date import date2jalali
from dmo.models import DmoDay, Dmo

User = get_user_model()

class TodoListManager(models.Manager):
    def get_todo_list(self, user, date):
        todo_list, _ = self.get_or_create(user=user, date=date)
        self._attach_dmo_items(todo_list)
        return todo_list

    def _attach_dmo_items(self, todo_list):
        date = date2jalali(todo_list.date)
        user_dmos = Dmo.objects.filter(user=todo_list.user, year=date.year, month=date.month)
        for dmo in user_dmos:
            if todo_list.items.filter(title=dmo.goal).exists():
                continue
            todo_list.items.create(title=dmo.goal)

    def move_lists_to_today(self):
        today = datetime.now()
        self.update(date=today)

    def move_lists_to_date(self, date):
        self.update(date=date)

class TodoListItemManager(models.Manager):
    def move_tasks_to_today_list(self):
        users = self.values('todo_list__user')
        if len(users) > 1:
            raise Exception('Multiple users found.')
        user = users[0]['todo_list__user']
        today_list = TodoList.objects.get_today(user)
        self.update(todo_list=today_list)

    def add_item(self, title, desc, user, date=None, stauts=None):
        if not date:
            date = datetime.now()
        if not status:
            status = TodoList.Statuses.PENDING
        todo_list = TodoList.objects.get_todo_list(user, date)
        self.create(todo_list=todo_list, title=title, desceription=desc, status=status)

class TodoList(models.Model):
    date = models.DateField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='کاربر',
                             related_name='todo_lists')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='آخرین ویرایش')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='ایجاد شده در')
    objects = TodoListManager()

    class Meta:
        verbose_name = 'Todo لیست'
        verbose_name_plural = 'Todo لیست'
        unique_together = ('date', 'user', )

    def __str__(self):
        return f'{self.user} - {self.date}'

    def move_list_to_date(self, to_date, commit=True):
        self.date = to_date
        if commit:
            self.save()

class TodoListItem(models.Model):

    class Statuses(models.IntegerChoices):
        PENDING = 0, 'در انتظار انجام'
        DONE = 100, 'انجام شد'
        NOT_DONE = 200, 'انجام نشد'

    todo_list = models.ForeignKey(TodoList, verbose_name='Todo', related_name='items',
                                  on_delete=models.CASCADE)
    title = models.CharField(max_length=255, verbose_name='عنوان')
    desc = models.TextField(verbose_name='توضیحات', blank=True)
    status = models.IntegerField(verbose_name='وضعیت', choices=Statuses.choices,
                                 default=Statuses.PENDING)
    dmo_day = models.OneToOneField(DmoDay, on_delete=models.CASCADE, verbose_name='دمو',
                                   related_name='todo_list_item', null=True, blank=True)
    updated_at = models.DateTimeField(auto_now=True, verbose_name='آخرین ویرایش')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='ایجاد شده در')
    objects = TodoListItemManager()

    class Meta:
        verbose_name = 'آیتم Todo لیست'
        verbose_name_plural = 'آیتم Todo لیست'

    def __str__(self):
        return self.title

    def change_status(self, status: Statuses, commit=True):
        self.status = status
        if commit:
            self.save()

    def done_task(self, commit=True):
        self.status = self.Statuses.DONE
        jalali_date = date2jalali(self.todo_list.date)
        dmo = Dmo.objects.filter(user=self.todo_list.user, goal=self.title,
                                 year=jalali_date.year, month=jalali_date.month
                                ).first()
        if dmo:
            dmo.complete(jalali_date.day, done=True)
        if commit:
            self.save()

    def undone_task(self, commit=True):
        self.end_datetime = datetime.now()
        self.status = self.Statuses.NOT_DONE
        jalali_date = date2jalali(self.todo_list.date)
        dmo = Dmo.objects.filter(user=self.todo_list.user, goal=self.title,
                                 year=jalali_date.year, month=jalali_date.month
                                ).first()
        if dmo:
            dmo.complete(jalali_date.day, done=False)
        if commit:
            self.save()

    def start_task(self):
        if self.time_tracks.filter(end_datetime__isnull=True).exists():
            raise Exception('Task is already started.')
        TodoListItemTimeTrack.objects.create(
            item=self,
            start_datetime=datetime.now(),
            end_datetime=None
        )

    def finish_task(self):
        now = datetime.now()
        self.time_tracks.filter(end_datetime=None).update(end_datetime=now)

    def toggle_start_stop(self):
        started_tracks = self.time_tracks.filter(end_datetime__isnull=True)
        if started_tracks.exists():
            started_tracks.update(end_datetime=datetime.now())
            return
        TodoListItemTimeTrack.objects.create(
            item=self,
            start_datetime=datetime.now(),
            end_datetime=None
        )

    def get_total_time_seconds(self):
        # db aggrigation doesn't work for some databases, so it's safer to use python
        time_tracks = self.time_tracks.filter(end_datetime__isnull=False).values('start_datetime', 'end_datetime')
        durations = [time['end_datetime'] - time['start_datetime'] for time in time_tracks]
        return reduce(lambda a, b: a+b, durations, timedelta(seconds=0)).seconds

    def get_last_ongoing_time_track(self):
        return self.time_tracks.filter(end_datetime__isnull=True).last()

class TodoListItemTimeTrack(models.Model):
    item = models.ForeignKey(TodoListItem, on_delete=models.CASCADE, verbose_name='آیتم',
                             related_name='time_tracks')
    start_datetime = models.DateTimeField(verbose_name='شروع', null=True, blank=True)
    end_datetime = models.DateTimeField(verbose_name='پایان', null=True, blank=True)
    updated_at = models.DateTimeField(auto_now=True, verbose_name='آخرین ویرایش')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='ایجاد شده در')

    class Meta:
        verbose_name = 'Todo لیست زمان'
        verbose_name_plural = 'Todo لیست زمان'

    def __str__(self):
        return f'{self.item}'


import os

# Directory containing the captured video files
video_directory = "captured_video"

# Function to rename files with sequential names
def rename_files(directory):
    if not os.path.exists(directory):
        print(f"Directory '{directory}' does not exist.")
        return

    file_list = os.listdir(directory)
    file_list.sort()  # Sort the files alphabetically
    count = 0

    for filename in file_list:
        if filename.endswith(".png"):  # Make sure to specify the correct file extension
            new_filename = f"{count:06d}.png"  # Format the new name with leading zeros
            old_path = os.path.join(directory, filename)
            new_path = os.path.join(directory, new_filename)

            try:
                os.rename(old_path, new_path)
                print(f"Renamed '{filename}' to '{new_filename}'")
                count += 1
            except Exception as e:
                print(f"Error renaming '{filename}': {e}")

# Call the function to rename files in the specified directory
rename_files(video_directory)