import sys
#from mpi4py import MPI
from neuron import h
from math import ceil
#h.nrnmpi_init()
import numpy as np
#import pylab as pl
import os
affix = sys.argv[1] # 5 if nrngui, 1 if python

v_init = -60


# Largescale toggles
# defines what functions are used
GABARUN=0
GKCA=1
GKA=1
PRINT = 1
IofV = 0
FGI = 0
RANDOM=0
PULSE = 0
STEADY = 1
GNAVARY = 0
SYNAPTIC = 0

DOCUMENT = 1
STEADYSTATE=0
VOLTSTEPRUN=0
STEP2=0
STEPLEN=10000
OFFSET = 500
HOLD=0
VSTEP=0
JAC = 0
ARRAY = 0
NTHREADS=64
FAST=0
GRAPH =0
USEOLD=0
VHOLD=-60
KV4PULSE=0
NMDAFUNC=0
UNIFORM=1
COSTIM=0
GABA=0
PRINTALL=0
RASTER=0
BIFURCATION =0
VERBOSE=0
GLUTARUN=0
POTASSIUM_NULLCLINE=0
READVALS = 1
ALIGN=0
ALIAT=5000
JUST_CURVE=0
PRC=0
RAMP=0
HISTO=0
DISTRIBUTE=0
DISTAL=0
SUMMATE=1
DRAW=0
custom_name = None

#MORPHO='KomandontovTemplate.hoc'

# template for distribution of channels
CURRENT_TEMPLATE='init_cell_katp.py'

# template for morphology - default simple is one compartment
MORPHO='template_simple.hoc' # sometimes goes to default

glutdata = 'Glu_d/Glu_d_Glu_80percentRw.dat' # not used by most functions


# recorded quantities.  Recorded in soma unless prepended with compartment.  Must be RANGE variable
#rec_list =['c1_NaMark','c2_NaMark','i1_NaMark','i2_NaMark','o1_NaMark','ika_hhb','ik_kca','cai','caski','ical_calhh','inmda_nmda','ais.v','dend[0].v','dend[11].v','ais.i2_NaMark','dend[0].i2_NaMark','dend[11].i2_NaMark','ais.o1_NaMark','dend[0].o1_NaMark','dend[4].o1_NaMark']#'gerg_erg','gkm_km']
""",'C1_GRC_NA','C2_GRC_NA','C3_GRC_NA','C4_GRC_NA','C5_GRC_NA',
'O_GRC_NA','OB_GRC_NA','I1_GRC_NA','I2_GRC_NA','I3_GRC_NA',
'I4_GRC_NA','I5_GRC_NA','I6_GRC_NA',
'L3_GRC_NA','L4_GRC_NA','L5_GRC_NA','L6_GRC_NA'
]"""
rec_list=['ihcn_hcn','icat_catchan','ika_hhb','ik_kca','ik_erg','dend[5].icat_catchan'] # slow potassium variables.

SUM_INDS=[0,1,2,3,4]
#rec_list=['dend[0].ik_kca','dend[4].cai','dend[4].caski','dend[4].cacicri','dend[0].cai','dend[0].caski','dend[0].cacicri']

#rec_list = ['c1_na8h', 'c2_na8h', 'c3_na8h', 'i1_na8h', 'i2_na8h', 'i3_na8h', 'i4_na8h', 'o_na8h']
#'gk_kca','gka2_hhb','qone_hhb','qtwo_hhb','ik_bkc','ikhh_hhb','n_bkc',
#'ika_hhb','ikhh_hhb','ik_kca','ik_erg','ik_km','ghcn_hcn'] # gka2 is actual conductance, gka is p^3q"""
			
# you break up lists on multiple lines.
SUMMED_INDICES=[] # all the slow potassium conductances ADD these into one term vs SUM_INDS sums over all segments
argdict = {'maxi':100,'mini':10,'freq':4} # this is probably overkill


from paramsdict import p_init as pstable # import default parameter dictionary (unordered labled list)
from paramsdict import argdict

axis =9

#EXTERN = 'array_parms.py' # default parameters for certain older function
#SUM_INDS=[]

# this bit allows for default parameters and function toggles to be set
# via command line.
affix2=''
for things in sys.argv:
	#print things
	if len(things.split('='))>1:
		blah = things.split('=')[0]
		try:
			val = float(things.split('=')[1])
		except:
			val=0
		if blah in pstable:
			if blah == 'both':
				temp=['both','1']
				pstable['gnahh']=pstable['gnahh']*val
				pstable['gkhh']=pstable['gkhh']*val
			else:
				temp = things.split('=')
				try:
					exec('pstable[\'%s\'] = %s' % (temp[0], temp[1]))
				except:
					exec('pstable[\'%s\'] = \'%s\'' % (temp[0], temp[1]))
				
				#print 'pstable[\'%s\'] = %s' % (things.split('=')[0], things.split('=')[1])
			if VERBOSE or temp[0] in ['nmdaamp','gabaamp','idel','idur','control','regtype']:
				affix2+='_'
				affix2+=things.split('=')[0]
				try:
					affix2+='%.2e' % float(things.split('=')[1])
				except:
					affix2+=things.split('=')[1]

			continue
		else:
			try:
				#print(things)
				exec(things)
			except:
				exec('%s =\'%s\'' % (things.split('=')[0],things.split('=')[1]))
			if things.split('=')[0] in ['VSTEP','STEP2','STEPLEN','OFFSET','SYNAPTIC','COSTIM','UNIFORM','NMDAFUNC','RAMP']:
				temp = things.split('=')
				affix2+='_%s%s' % (temp[0],temp[1])
#print CURRENT_TEMPLATE
#quit()				
#print(pstable['syntype'])
#SUM_INDS=[1,2,3,4]

if not SUMMATE:
	SUM_INDS=[]


#print(EXTERN)
#quit()
if custom_name !=None:
	affix2+='_%s' % str(custom_name)


if DOCUMENT:
	path = os.getcwd() + '/' + affix+ '/'
	try:
		os.mkdir(path)
	except:
		pass
	os.system('cp blockhh3.mod %s.' %path)
	os.system('cp NaMarkov.mod %s.' %path)
	os.system('cp paramsdict.py %s.' %path)
	
	
	

h.load_file("nrngui.hoc")
#h.load_file("template_SNc.hoc") # for rebound

h.load_file('%s' % MORPHO)
#print MORPHO
#quit()
if MORPHO!= 'template_simple.hoc':
	fp = open(MORPHO,'r')
	line = fp.readline()
	temp = line.split()
	TYPE=temp[1]
else:
	TYPE = 'SIMPLE'


exec('from %s import init, to_shreds_you_say' % CURRENT_TEMPLATE.split('.')[0]) #depblock only has somatic assignments for single compartment
import new_geomnseg as geom


print(TYPE)
FIXED_DISTRO = None
	

class fullneuron:
	def __init__(self,i, parms, args=[0,1]):
		h.pop_section()
		self.p1 = args[0]
		self.p2 = args[1]
		self.internal = parms
		#print 'make'
		exec('self.nrn = h.%s()' % TYPE)
		#self.nrn = (h.SIMPLE())
		#self.nrn = MF.add_AIS(self.nrn,35,100,0.9)
		
		#print self.ais.L, self.ais.diam
		
		#to_shreds_you_say(self.nrn,parms['chop'])# create morphology template
		self.dt = 0.025 # 20khz
		#print 'init'
		init(self.nrn,self.internal) # from initcell - using dict parameters
		
		geom.geom_nseg(self.nrn)
		
		for s in self.nrn.all: # this should move
			if TYPE=='SIMPLE':
				s.L = self.internal['size']
				s.diam = 5
				if self.internal['gcat']> 0: # normally, gcat is not somatic
					s.insert('catchan')
					s.gcatbar_catchan = 100e-6*self.internal['gcat']
		
		#temp = np.arange(1000,4000,self.dt)
		self.srec = h.Vector()# spike times

		self.ntc = h.NetCon(self.nrn.soma(0.5)._ref_v,None,sec=self.nrn.soma)
		self.ntc.threshold = -20
		self.ntc.record(self.srec)
		#self.vrec.record(self.nrn.soma(0.5)._ref_v,self.tvec)#"""
		#print 'areas'
		# this should all be in init
		
	def __del__(self):
		if VERBOSE:
			print('killing', self.__class__.__name__)
		else:
			pass

dopa = fullneuron # for legacy code


def sine_func(t,freq=pstable['freq'],maxi=40,mini=10):
	#if t==0:
	#	print(freq, maxi, mini)
	temp = (1.0+np.sin(2*np.pi*1e-3*freq*t))/2.0
	temp *= (maxi-mini)
	temp += mini
	return temp
	
def cos_func(t,freq=1,maxi=60,mini=2):
	#if t==0:
	#	print(freq, maxi, mini)
	temp = (1.0+np.cos(2*np.pi*1e-3*freq*t))/2.0
	temp *= (maxi-mini)
	temp += mini
	return temp
	
def window_func(t,on=pstable['won'],off=pstable['woff'],fon=pstable['fon'],foff=pstable['foff']):
	if t%int(on+off)<on:
		temp=fon
	else:
		temp=foff
	return temp
	
def randomized_window_func(t,on=100,off=150,fmax=100,fmin=2,foff=0):
	if t%int(on+off)<on:
		temp=np.random.random()*(fmax-fmin)+fmin
	else:
		temp=foff
	return temp

if GABARUN:
	from synapse_funcs import gaba_run, gen_netstim,lfnoise

	gaba_run(rec_list,dopa,pstable=pstable,func=window_func,funcargs={'fon':pstable['fon']},args=[affix,affix2],ncells=int(pstable['ncells']),stype=pstable['syntype'],nmdafunc=window_func,nmdaargs={'on':1000,'off':0,'fon':pstable['foff'],'foff':0},nmdacells=1,RAMP=RAMP, HISTO=HISTO, SUMMATE=SUMMATE, DISTRIBUTE=DISTRIBUTE, DISTAL=DISTAL, SUM_INDS=SUM_INDS, DRAW=DRAW) # yes foff	
		#gaba_run(rec_list,dopa,pstable=pstable,func=lfnoise,funcargs={'mean':pstable['fon'],'var':0.001*pstable['fon'],'maxfreq':0.002},args=[affix,affix2],ncells=int(pstable['ncells']),stype=pstable['syntype'],nmdafunc=lfnoise,nmdaargs={'mean':pstable['fon'],'var':0.25*pstable['fon'],'maxfreq':0.002},nmdacells=1) # yes foff	
		


if RUN and PRINT and GRAPH:
	if STEADY:
		os.system('xmgrace steady_%s_*.dat' % (affix))
	elif SYNAPTIC:
		os.system('xmgrace nmda_%s_*.dat' % (affix))
	else:
		os.system('xmgrace ramp_%s_*.dat' % (affix))
		
if GABARUN and GRAPH:
	os.system('xmgrace -block GABA_*%s*.dat -bxy 1:2' % (affix))
	#os.system('xmgrace -block GABA_*%s*.dat -bxy 1:4 -bxy 1:5 -bxy 1:6' % (affix))
	#os.system('xmgrace -block GABA_*%s*.dat -bxy 2:3' % (affix))
	

if GABA_ARRAY and GRAPH:
	os.system('python heat_plot.py stats_*%s%s.dat %d' % (affix,affix2,axis))
	
if IofV and GRAPH:
	os.system('xmgrace IofV_%s*.dat' % (affix))
if DOCUMENT:
	try:
		os.system('mv *%s*.dat %s/.' % (affix, affix))
		quit()
	except:
		quit()
		
quit()