// File: /workspace/github_c_makefile_star2_O1/stonezwr[P]SpiKL-IP/neuron.C
// Function: Neuron::LSMNextTimeStep(int, _IO_FILE*, bool, int)
void Neuron::LSMNextTimeStep(int t, FILE * Foutp, bool train, int end_time){

    if(_mode == DEACTIVATED) return;
    if(_mode == READCHANNEL ){
        if(_mode != READCHANNEL){
            // if training the input-reservoir/reservoir-readout synapses, need to keep track the cal!
            _lsm_v_mem_pre = _lsm_v_mem;
            _lsm_calcium_pre = _lsm_calcium;
            _lsm_calcium -= _lsm_calcium/TAU_C;
        }
        if(_t_next_spike == -1) return;
        if(t < _t_next_spike) return;
        if(_mode != READCHANNEL){
            _lsm_calcium += one;
        }

        /** Hand the firing behavior here for both input neurons and reservoir neurons */
        /** @param1: is the neuron only used to output spike? **/
        HandleFiringActivity(true, t, train);
        _fired = true;

        _t_next_spike = _lsm_channel->NextSpikeT();
        if(_t_next_spike == -1) {
            _network->LSMChannelDecrement(_lsm_channel->Mode()); 
        }
        return;
    }
    

    // the following code is to simulate the mode of NORMAL, WRITECHANNEL, and STDP
    _lsm_v_mem_pre = _lsm_v_mem;
    _lsm_calcium_pre = _lsm_calcium;
    _lsm_calcium -= _lsm_calcium/TAU_C;

    if((_teacherSignal==1)&&(_lsm_calcium < LSM_CAL_MID+1)){
        _lsm_v_mem += 20;
    }else if((_teacherSignal==-1)&&(_lsm_calcium > LSM_CAL_MID-1)){
        _lsm_v_mem -= 15*0.75;
    }

    list<Synapse*>::iterator iter;

    int pos;
    double value;
	if(_name[0]=='r')
		ExpDecay(_lsm_v_mem, _lsm_t_m_c);
	else
		ExpDecay(_lsm_v_mem, LSM_T_M_C);
    ExpDecay(_lsm_state_EP, _lsm_tau_EP);
    ExpDecay(_lsm_state_EN, _lsm_tau_EN);
    ExpDecay(_lsm_state_IP, _lsm_tau_IP);
    ExpDecay(_lsm_state_IN, _lsm_tau_IN);

    // sum up the effect
    _lsm_state_EP += _prev_delta_ep;
    _lsm_state_EN += _prev_delta_en;
    _lsm_state_IP += _prev_delta_ip;
    _lsm_state_IN += _prev_delta_in;

    double temp = NOrderSynapticResponse();
    _lsm_v_mem += _lsm_R*temp/_lsm_t_m_c;
	_lsm_input=temp;
	if(temp>0){
		_fire_start=true;
	}

    if(_lsm_ref > 0){
        _lsm_ref--;
        _lsm_v_mem = LSM_V_REST;
        _fired = false;
        return;
    }

    _fired = false;

    if(_lsm_v_mem > _lsm_v_thresh){
        _lsm_calcium += one;

        // 1. handle the _outputSyns after the neuron fires and activate the _outputSyns
        // 2. keep track of the t_spike_pre for the corresponding syns
        // 3. @para1: whether or not the current neuron is only used as a dummy input
        HandleFiringActivity(false, t, train);
        _fired = true;

        _lsm_v_mem = LSM_V_RESET;

		_lsm_ref = LSM_T_REFRAC;

        if(_name[0] == 'o' || _name[0] == 'h'){
            _f_count ++;
            assert(t > (_fire_timings.empty() ? -1 : _fire_timings.back()));
            _fire_timings.push_back(t);
        }
		else
			_f_count++;

        if(_mode == WRITECHANNEL&&_generate_transient){
            if(_lsm_channel == NULL){
                cout<<"Failure to assign a channel ptr to the neuron: "<<_name<<endl;
                assert(_lsm_channel);
            }
            _lsm_channel->AddSpike(t);
        }

    }
#ifdef SPIKL_IP
    if(_SpiKL_ip && _network->LSMGetNetworkMode()==TRANSIENTSTATE)  
        SpiKL_IP(t);
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x10, %rsp
movl %esi, 0xc(%rsp)
movl 0x8(%rdi), %eax
testl %eax, %eax
je 0x7793
movq %rdi, %rbx
cmpl $0x1, %eax
jne 0x73e4
movl 0x218(%rbx), %edx
cmpl $-0x1, %edx
sete %dil
cmpl %esi, %edx
setg %dl
orb %dil, %dl
jne 0x7793
cmpl $0x1, %eax
je 0x736f
movsd 0x178(%rbx), %xmm0
addsd 0x10279(%rip), %xmm0    # 0x175e0
movsd %xmm0, 0x178(%rbx)
movq 0x18(%rbx), %r15
movq 0x20(%rbx), %r12
cmpq %r12, %r15
je 0x743f
movzbl %cl, %ebp
movq (%r15), %r14
movq %r14, %rdi
callq 0xc3e2
cmpl $0x0, 0x8(%rax)
je 0x739b
cmpb $0x0, 0x13(%r14)
je 0x73a9
addq $0x8, %r15
cmpq %r12, %r15
jne 0x7383
jmp 0x743f
movq %r14, %rdi
callq 0xc3f0
movq 0x10(%rbx), %rax
cmpb $0x69, (%rax)
je 0x739b
cmpl $0x1, 0x8(%rbx)
jne 0x739b
movq %r14, %rdi
callq 0xc268
testb %al, %al
je 0x739b
movq 0x120(%rbx), %rsi
movq %r14, %rdi
movl $0x1, %edx
movl %ebp, %ecx
callq 0xc44c
jmp 0x739b
movsd 0x168(%rbx), %xmm1
movsd %xmm1, 0x170(%rbx)
movsd 0x178(%rbx), %xmm2
movsd %xmm2, 0x180(%rbx)
movsd 0x101dc(%rip), %xmm0    # 0x175e8
mulsd %xmm2, %xmm0
addsd %xmm2, %xmm0
movsd %xmm0, 0x178(%rbx)
movl 0x114(%rbx), %eax
cmpl $0x1, %eax
jne 0x7483
movsd 0x101c9(%rip), %xmm2    # 0x175f8
ucomisd %xmm0, %xmm2
jbe 0x7483
movsd 0x101b3(%rip), %xmm2    # 0x175f0
jmp 0x749a
movb $0x1, 0x130(%rbx)
movq 0x210(%rbx), %rdi
callq 0x3f06
movl %eax, 0x218(%rbx)
cmpl $-0x1, %eax
jne 0x7793
movq 0x120(%rbx), %rdi
movq 0x210(%rbx), %rax
movl 0x44(%rax), %esi
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x11506
cmpl $-0x1, %eax
jne 0x74a6
ucomisd 0x10178(%rip), %xmm0    # 0x17608
jbe 0x74a6
movsd 0x10166(%rip), %xmm2    # 0x17600
addsd %xmm2, %xmm1
movsd %xmm1, 0x168(%rbx)
movq 0x10(%rbx), %rax
cmpb $0x72, (%rax)
jne 0x74c9
movsd 0x168(%rbx), %xmm1
movapd %xmm1, %xmm2
divsd 0x1f0(%rbx), %xmm2
subsd %xmm2, %xmm1
jmp 0x74e1
movsd 0x168(%rbx), %xmm2
movsd 0x1010f(%rip), %xmm1    # 0x175e8
mulsd %xmm2, %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x168(%rbx)
movsd 0x1a8(%rbx), %xmm4
movsd 0x188(%rbx), %xmm2
movsd 0x190(%rbx), %xmm5
movapd %xmm2, %xmm3
divsd %xmm4, %xmm3
subsd %xmm3, %xmm2
movsd 0x1b0(%rbx), %xmm7
movapd %xmm5, %xmm3
divsd %xmm7, %xmm3
subsd %xmm3, %xmm5
movsd 0x1b8(%rbx), %xmm6
movsd 0x198(%rbx), %xmm3
movapd %xmm3, %xmm8
divsd %xmm6, %xmm8
subsd %xmm8, %xmm3
movsd 0x1c0(%rbx), %xmm8
movsd 0x1a0(%rbx), %xmm9
movapd %xmm9, %xmm10
divsd %xmm8, %xmm10
addsd 0xd0(%rbx), %xmm2
subsd %xmm10, %xmm9
movsd %xmm2, 0x188(%rbx)
addsd 0xd8(%rbx), %xmm5
movsd %xmm5, 0x190(%rbx)
addsd 0xe0(%rbx), %xmm3
movsd %xmm3, 0x198(%rbx)
addsd 0xe8(%rbx), %xmm9
movsd %xmm9, 0x1a0(%rbx)
subsd %xmm5, %xmm2
subsd %xmm7, %xmm4
divsd %xmm4, %xmm2
subsd %xmm9, %xmm3
subsd %xmm8, %xmm6
divsd %xmm6, %xmm3
addsd %xmm2, %xmm3
movsd 0x1d8(%rbx), %xmm2
mulsd %xmm3, %xmm2
divsd 0x1f0(%rbx), %xmm2
addsd %xmm1, %xmm2
movsd %xmm2, 0x168(%rbx)
movsd %xmm3, 0x1f8(%rbx)
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm3
jbe 0x75fa
movb $0x1, 0x1e8(%rbx)
movl 0x208(%rbx), %eax
testl %eax, %eax
jle 0x7623
decl %eax
movl %eax, 0x208(%rbx)
movq $0x0, 0x168(%rbx)
movb $0x0, 0x130(%rbx)
jmp 0x7793
movb $0x0, 0x130(%rbx)
ucomisd 0x1d0(%rbx), %xmm2
jbe 0x7772
addsd 0xffa0(%rip), %xmm0     # 0x175e0
movsd %xmm0, 0x178(%rbx)
movq 0x18(%rbx), %r15
movq 0x20(%rbx), %r12
cmpq %r12, %r15
je 0x767b
movq (%r15), %r14
movq %r14, %rdi
callq 0xc3e2
cmpl $0x0, 0x8(%rax)
je 0x7675
cmpb $0x0, 0x13(%r14)
jne 0x7675
movq %r14, %rdi
callq 0xc3f0
addq $0x8, %r15
jmp 0x7650
movb $0x1, 0x130(%rbx)
movq $0x0, 0x168(%rbx)
movl $0x2, 0x208(%rbx)
movq 0x10(%rbx), %rax
movzbl (%rax), %eax
cmpl $0x6f, %eax
je 0x76a8
cmpl $0x68, %eax
jne 0x76c7
incl 0x12c(%rbx)
movl 0xc(%rsp), %eax
movq 0x90(%rbx), %rsi
cmpq %rsi, 0x88(%rbx)
je 0x76cf
movl -0x4(%rsi), %ecx
jmp 0x76d4
incl 0x12c(%rbx)
jmp 0x7705
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpl %ecx, %eax
jle 0x77a0
cmpq 0x98(%rbx), %rsi
je 0x76f4
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x90(%rbx)
jmp 0x7705
leaq 0x88(%rbx), %rdi
leaq 0xc(%rsp), %rdx
callq 0x4476
cmpl $0x2, 0x8(%rbx)
jne 0x7772
movsd 0x200(%rbx), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x771f
jnp 0x7772
cmpq $0x0, 0x210(%rbx)
jne 0x7762
movq 0x198a0(%rip), %r14     # 0x20fd0
leaq 0xfff8(%rip), %rsi      # 0x1772f
movl $0x2f, %edx
movq %r14, %rdi
callq 0x3340
movq 0x10(%rbx), %rsi
movq %r14, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3160
cmpq $0x0, 0x210(%rbx)
je 0x77bf
movq 0x210(%rbx), %rdi
movl 0xc(%rsp), %esi
callq 0x3ddc
cmpb $0x1, 0x140(%rbx)
jne 0x7793
movq 0x120(%rbx), %rax
cmpl $0x0, 0x2c0(%rax)
jne 0x7793
movq %rbx, %rdi
callq 0x77de
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0xff0a(%rip), %rdi      # 0x176b1
leaq 0xff3b(%rip), %rsi      # 0x176e9
leaq 0xff3d(%rip), %rcx      # 0x176f2
movl $0x18e, %edx            # imm = 0x18E
callq 0x31b0
leaq 0xff99(%rip), %rdi      # 0x1775f
leaq 0xff1c(%rip), %rsi      # 0x176e9
leaq 0xff1e(%rip), %rcx      # 0x176f2
movl $0x197, %edx            # imm = 0x197
callq 0x31b0