// Na Ion Channel Dynamics (Baker 2003)
//
// Copyright 2007 John L Baker. All rights reserved.
//
// This software is provided AS IS under the terms of the Open Source
// MIT License. See http://www.opensource.org/licenses/mit-license.php.
//
// File: ionchan_na_baker_2003.h
//
// Release:		1.0.0
// Author:		John Baker
// Updated:		14 July 2006
//
// Description:
//
// This header file contains the classes used to implement
// the sodium (Na) channel based primarily on data from the Gasparini and Magee
// 2002 article for dendritic channels and Pan and Colbert for soma and axon.
// Persistent Na currents are better characterized in EC neurons and the
// voltage dependency there is used here for CA3 (see below).
//
// Pan & Colbert found that half of the Na current was not inactivated at
// +20mV relative to rest (i.e. at approx -50mV). To allow for this and to
// support slow inactivation, a special s gate is added to the usual model.
// The h gate is voltage shifted so that its vhalf is approximately -50mV
// and the combination of h*s gates is the steady-state inactivation voltage 
// response measured by Gasparini & Magee for dendrites and Colbert & Pan
// for soma. No s gate is used for axon channels.
//
// In EC, persistent sodium currents occur in bursts which have time
// constants largely independent of voltage (see Magistretti and Alonso). 
// No attempt is made here to model these kinetics because experimental 
// data is not sufficient to do so. Slow inactivation is included primarily
// to make resting voltage more stable. French extrapolates the I-V 
// relationship to give a reversal potential of +8mV for this current,
// but a reversal potential from Magistretti and Alonso is used instead.
//
// Q10 values may be inaccurate. Activation gate Q10 is chosen as typical
// of activation gates. Note that the minimum tau value is not affected by
// temperature. For inactivation, Sah et al. show a difference in Na current 
// decay times at different temperatures. Values used here are at best rough 
// estimates and are chosen as a compromise with the inactivation time constant 
// found by Pan & Colbert (37 msec at -50mV) for 32 deg C with that found by 
// Costa at 22 deg C. Because of the relationship between activation and 
// inactivation processes, inactivation at depolatized potentials may be less
// sensitive to temperature. Differences in slow inactivation as measured by
// Mikus et al. and by Colbert et al. could be due to temperature, in which
// case a Q10 of 2-3 would be appropriate. 
//
// References:
//
// Colbert CM, Magee JC, Hoffman DA, Johnston D (1997). Slow recovery from
// inactivation of Na+ channels underlies the activity-dependent attentuation
// of dendritic action potentials in hippocampal CA1 pyramidal neurons.
// J Neurosci. 17, 6512-6521
// 
// Colbert CM and Pan E (2002). Ion channel properties underlying axonal action 
// potential initiation in pyramidal neurons. Nature Neuroscience 5, 533-538.
//
// Costa PF, 1996. The kinetic parameters of sodium currents in maturing
// acutely isolated rat hippocampal CA1 neurones. 
// Developmental Brain Research 91,29-40.
//
// French CR, Sah P, Buckett KJ, and Gage PW (1990). A voltage-dependent
// persistent sodium current in mammalian hippocampal neurons.
// J. Gen Physiol. 95(6), 1139-1157.
//
// Gasaprini S and Magee JC, 2002. Phosphorylation-dependent differences
// in the activation properties of distal and proximal dendritic Na+
// channels in rat CA1 hippocampal neurons. J. Physiology 541.3, 665-672.
//
// Hu H, Vervaeke K, and Storm J. (2002). Two forms of electrical 
// resonance at theta frequencies, generated by M-current, h-current
// and persistent Na+ current in rat hippocampal pyramidal cells.
// J. Physiology 545, 783-805.
//
// Magee JC, Johnston D (1995). Characterization of single
// voltage-gated Na+ and Ca++ channels in apical dendrites
// of rat CA1 pyramidal neurons. J. Physiology 487, 67-90.
//
// Magistretti J and Alonso A (1999). Biophysical properties of slow
// voltage-dependent inactivation of a sustained sodium current in
// entorhinal cortex layer II principal cells. 
// J. Gen. Physiol. 114, 491-509.
//
// Magistretti J and Alonso A (2002). Fine gating properties of channels
// responsible for persistent sodium current generation in entorhinal cortex
// neurons. J. Gen. Physiol. 120, 855-873.
//
// Mikus T, Jung H, and Spruston N (1999). Properties of slow, cumulative
// sodium channel inactivation in rat hippocampal CA1 pyramidal neurons.
// Biophysical Journal 76, 846-860.
//
// Pan E and Colbert CM, 2001. Subthreshold inactivation of Na+ and
// K+ channels supports activity-dependent enhancement of back-propagating
// action potentials in hippocampal CA1. J. Neurophysiology 85, 1013-1016.
//
// Sah P, Gibb AJ, and Gage PW, 1988. The sodium current underlying action
// potentials in guinea pig hippocampal CA1 neurons. 
// J. Gen. Physiol. 91, 373-398.
//
// Tsubokawa H and Ross WN (1997). Muscarinic modulation of spike back-
// propagation in the apical dendrites of hippocampal CA1 pyramidal neurons.
// J Neurosci. 17, 5782-5791. 


// Only include this header once
#ifndef __IONCHAN_NA_BAKER_2003_H_
#define __IONCHAN_NA_BAKER_2003_H_

#include "bnsf.h"

using namespace std;
using namespace BNSF;

namespace BAKER_2003 {

	// ================================================================
	// Common superclasses used in building Na channel objects
	// ================================================================

	// Abstract Na h gate ---------------------------------------------

	// Gate properties take into account state transition open->inact
	// in which channel inactivation is dependent on open state value.
	// Voltage sensitivity is a combination of a single energy barrier
	// with adjustments for dependency on the activation (m) gate.

	// The activation gate must be an order 3 gate, that is activation
	// open probability is m*m*m. alpha() and beta() functions only return the
	// energy barrier component as does printAlphaBetaTable.

	// Parameters for the energy barrier component are provided in subclasses.

	class Abstract_Na_h_gate : public EnergyBarrierTabGate {

	public:

		// Constructors and destructor
		Abstract_Na_h_gate(IonChannel* mgate=NULL);
		virtual ~Abstract_Na_h_gate();

		// Accessors for activation gate
		inline  IonChannel*			mgate()					{ return _mgate; }
		virtual void				mgate(IonChannel* mg)	{ _mgate=mg; }

		// Establish dependency on mgate to ensure consistent evaluation order
		virtual bool				hasPrequisites() { return true; }
		virtual ModelComponent*		prerequisite() { return mgate(); }
		
		// Fastpath computation of derivatives
		// including effects of activation gate.
		virtual void				computeDerivatives();

		// Fastpath computation of local state update
		// including effects of activation gate.
		virtual bool				canPerformLocalUpdate() { return true; }
		virtual void				localStateUpdate(SimTime h, CNStepType stepType);

		// Save parameter values for fast path on simulation started
		virtual void				simulationStarted();

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char** stateLabels() {
			static const char* sl[] = { "h" }; return sl; }

		// Subclass responsiblities ----------------------------

		// Specify parameter for rate of additional open->inact transitions
		virtual Number				inactRate() = 0;

		// Specify parameter for additional value added to computed tau.
		// This functions like tauMin but is after the energy barrier component
		// and m-gate dependent component are combined.
		virtual Number				tauZero() = 0;

	protected:
		IonChannel*					_mgate;
		Number						_inactRate;
		Number						_tauZero;
	};

	// Na h gate ------------------------------------------

	// This gate provides fast inactivation for the Na channel.
	// It is intended to be used with a matching s gate and the
	// product of the two is Na channel inactivation.

	class Na_h_gate : public Abstract_Na_h_gate {

	public:
		// Constructors and destructor
		Na_h_gate(IonChannel* mgate=NULL) : Abstract_Na_h_gate(mgate) {}
		virtual ~Na_h_gate() {}

		// Temperature dependency (see notes above).
		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return  2; }

		// Voltage dependency from Gasparini & Magee adjusted to work
		// with an s gate. The slope is adjusted to take into account 
		// the effect of m-gate state on inactivation.
		virtual Number	Vhalf()			{return -50*UOM::mV; }
		virtual Number	slope()			{return -8*UOM::mV; }
		
		// Time constants. There is something of a conflict between
		// values from Costa (whole cell) and those of Pan & Colbert
		// (in dendrite) because different temperatures are used.
		// These values attempt to split the difference. There is also a
		// suggestion in later work by Colbert et al. (SFN2003 poster)
		// that the 37 msec value may be high.
		virtual Number	tauMax()		{return  45*UOM::msec; }
		virtual Number	gamma()			{return  0.2f; }

		// Specify parameter for rate of additional open->inact transitions.
		virtual Number	inactRate()		{ return 1.5/UOM::msec; }

		// Specify parameter for additional value added to computed tau.
		// This functions is like tauMin but is after the energy barrier 
		// component and m-gate dependent component are combined.
		virtual Number	tauZero()		{return  0.4*UOM::msec; }

		// Because this gate uses the current value of the m gate,
		// it may not be second order accurate in time.
		virtual bool	isSecondOrderAccurate() { return false; }

	protected:
		virtual AlphaBetaEntry**	pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};
	
	// Abstract Na s gate --------------------------------------------

	// This gate controls slow activation. The gate is adjusted to result
	// such that a combination of h*s is the steady state inactivation
	// measured. Subclasses extend by supplying parameters.

	class Abstract_Na_s_gate : public EnergyBarrierTabGate {

	public:
		// Constructors and destructor
		Abstract_Na_s_gate(
			bool isDisabled=false,	// set gateDisabled on or off
			Number dval=0.5f);		// set default disabled value

		virtual ~Abstract_Na_s_gate();

		// Temperature dependency
		virtual Number	ratedTempC()	{return  37; }
		virtual Number	Q10()			{return	 1; }

		// Allow for difference between h and s gate Vhalf values.
		// To have h*s be an ideal sigmoidal curve we would set this
		// to be exp(dV/k) where dV is the different in Vhalf values
		// and k the common slope variable. The value here is exp(-17/8).
		virtual Number	xinfAbsMin()	{return 0.12f; }

		// Access a switch that turns gate on or off. If off, the gate always
		// returns the gate disable value regardless of voltage.
		inline  bool	gateDisabled()	{return _gateDisabled; }
		virtual void	gateDisabled(bool flag) { _gateDisabled = flag; }

		// Access the static value used when the gate is off.
		inline	Number	disabledValue() {return _disabledValue; }
		virtual void	disabledValue(Number s) { _disabledValue = s; }

		// Access the static time constant when the gate is off
		inline  Number	disabledTau() {return _disabledTau; }
		virtual void	disabledTau(Number tau) { _disabledTau = tau; }

		// Special interfaces to be overridden when gate is disabled
		virtual void	computeDerivatives();
		virtual void	localStateUpdate(SimTime h, CNStepType stepType);

		// Provide accessors for Hodgkin-Huxley rate values
		// adjusted for gate status as needed.
		virtual Number	alpha();
		virtual Number	beta();

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char** stateLabels() {
			static const char* sl[] = { "s" }; return sl; }

	protected:
		bool			_gateDisabled;		// flag indicating disabled by ACh
		Number			_disabledValue;		// Xinf value when disabled
		Number			_disabledTau;		// tau value when disabled
	};

	// Abstract Na channel ------------------------------------------

	class Abstract_Na_channel : public M3HSIonChannel {

	public:

		// Constructor and destructor
		Abstract_Na_channel() { _sGate=NULL; }
		virtual ~Abstract_Na_channel() {}

		// Control current s gate status
		virtual bool	sGateDisabled()					{ return _sGate->gateDisabled(); }
		virtual void	sGateDisabled(bool status)		{ _sGate->gateDisabled(status); }

		virtual Number	sGateDisabledValue()			{ return _sGate->disabledValue(); }
		virtual void	sGateDisabledValue(Number x)	{ _sGate->disabledValue(x); }

	protected:
		Abstract_Na_s_gate*		_sGate;			// subclass must initialize
	};

	// ================================================================
	// Na channel class definitions
	// ================================================================

	// Proximal Na channel -------------------------------------------

	class Proximal_Na_m_gate : public EnergyBarrierTabGate {

	public:
		// Constructors and destructor
		Proximal_Na_m_gate() {}
		virtual ~Proximal_Na_m_gate() {}

		// Estimated temperature sensitivity
		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return	 4; }

		// Order 3 gate for Vhalf=-12.0mV, k=8.1mV (Gasparinit & Magee)
		virtual Number	Vhalf()			{return -25.5*UOM::mV; }
		virtual Number	slope()			{return  10.0*UOM::mV; }

		// Time constants similar to those in Costa
		virtual Number	tauMax()		{return 0.2*UOM::msec; }
		virtual Number	tauMin()		{return 0.05*UOM::msec; }
		virtual Number	gamma()			{return 0.5f; }

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char** stateLabels() {
			static const char* sl[] = { "m" }; return sl; }

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};

	class Proximal_Na_s_gate : public Abstract_Na_s_gate {

	public:
		// Constructors and destructor
		Proximal_Na_s_gate(
			bool isDisabled=false,	// set gateDisabled on or off
			Number dval=0.5f)		// set default disabled value
			: Abstract_Na_s_gate(isDisabled,dval) {}

		virtual ~Proximal_Na_s_gate() {}

		// Steady state inactivation from Gasparini & Magee.
		virtual Number	Vhalf()			{return -66.8*UOM::mV; }
		virtual Number	slope()			{return -6.8*UOM::mV; }

		// Time constant. Entry into slow inactivation is reduced
		// for somatic (and also proximal) channels but recovery
		// times are the same as for dendrites. This is modeled
		// by making the time constant less depedent on voltage.
		virtual Number	tauMax()		{return  1300*UOM::msec; }
		virtual Number	tauMin()		{return  800*UOM::msec; }

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static  AlphaBetaEntry*		_abTable;
	};

	class Proximal_Na_channel : public Abstract_Na_channel {
	
	public:
		// Constructors and destructor
		Proximal_Na_channel(
			Number		gSpVal=0,					// specific conductance value
			bool		sGateDisabled=false,		// s-gate disabled or not
			Number		sGateValue=0.5);			// fixed s-gate value if disabled
		virtual ~Proximal_Na_channel() {}

		// Reversal potential for Na+
		virtual Number Vrev() { return _Vrev; }

	protected:
		static const Number		_Vrev;
	};

	// Distal Na channel -------------------------------------------

	class Distal_Na_m_gate : public EnergyBarrierTabGate {

	public:

		// Constructors and destructor
		Distal_Na_m_gate() {}
		virtual ~Distal_Na_m_gate() {}

		// Estimated temperature sensitivity
		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return	 4; }

		// Order 3 gate for Vhalf=-20.4mV, k=8.2mV (Gasparinit & Magee)
		virtual Number	Vhalf()			{return -34.1*UOM::mV; }
		virtual Number	slope()			{return  10.1*UOM::mV; }

		// Time constants similar to those in Costa
		virtual Number	tauMax()		{return 0.2*UOM::msec; }
		virtual Number	tauMin()		{return 0.05*UOM::msec; }
		virtual Number	gamma()			{return 0.5f; }

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char** stateLabels() { 
			static const char* sl[] = { "m" }; return sl; }

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};

	class Distal_Na_s_gate : public Abstract_Na_s_gate {

	public:
		// Constructors and destructor
		Distal_Na_s_gate(
			bool isDisabled=false,	// set gateDisabled on or off
			Number dval=0.5f)		// set default disabled value
			: Abstract_Na_s_gate(isDisabled,dval) {}

		virtual ~Distal_Na_s_gate() {}

		// Steady state inactivation from Gasparini & Magee.
		virtual Number	Vhalf()			{return -63.6*UOM::mV; }
		virtual Number	slope()			{return -6.3*UOM::mV; }

		// Time constants (see Mikus et al. figures 7 & 8).
		virtual Number	tauMax()		{return 1300*UOM::msec; }
		virtual Number	tauMin()		{return 390*UOM::msec; }

		// For these gates, ignore the disable request
		// since they are not affected by ACh (Tsubokawa et al)
		inline  bool	gateDisabled()	{return _gateDisabled; }
		virtual void	gateDisabled(bool flag) {}

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static  AlphaBetaEntry*		_abTable;
	};

	class Distal_Na_channel : public Abstract_Na_channel {
	
	public:

		// Constructors and destructor
		Distal_Na_channel(
			Number		gSpVal=0,					// specific conductance value
			bool		sGateDisabled=false,		// s-gate disabled or not
			Number		sGateValue=0.5);			// fixed s-gate value if disabled
		virtual ~Distal_Na_channel() {}

		// Reversal potential for Na+
		virtual Number Vrev() { return _Vrev; }

	protected:
		static const Number		_Vrev;
	};

	// Blended Proximal-Distal Na Channel  ----------------------------

	class Blended_Na_m_gate : public BlendedIonGate {
	
	public:
		// Constructors and destructor
		Blended_Na_m_gate(Number bratio=0.5) : BlendedIonGate(
			new Proximal_Na_m_gate,
			new Distal_Na_m_gate,
			bratio) {}
		virtual ~Blended_Na_m_gate() {}

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char**	stateLabels() {
			static const char* sl[] = { "m" }; return sl; }
	};

	// Blended_Na_s_gate. One problem here is that this inherits from a
	// a different hierarchy. Logic for disabling the s-gate is replicated
	// here and in the blended Na channel.

	class Blended_Na_s_gate : public BlendedIonGate {
	
	public:
		// Constructors and destructor
		Blended_Na_s_gate(Number bratio=0.5,	// blend ratio
			bool isDisabled=false,				// set gateDisabled on or off
			Number dval=0.5f);					// set default disabled value
		virtual ~Blended_Na_s_gate();

		// Access a switch that turns gate on or off. This is a
		// pass-thru to the underlying gates
		inline  bool	gateDisabled()	{return sgate1()->gateDisabled(); }
		virtual void	gateDisabled(bool flag);

		// Access the static value used when the gate is off.
		// This is a pass-thru to the underlying gates
		inline	Number	disabledValue() {return sgate1()->disabledValue(); }
		virtual void	disabledValue(Number s);

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char**	stateLabels() {
			static const char* sl[] = { "s" }; return sl; }

	protected:
		bool			_gateDisabled;
		Number			_disabledValue;

		// Do casts to get appropriate gate types - ugly but necessary
		inline  Abstract_Na_s_gate* sgate1() { return (Abstract_Na_s_gate*) gate1(); }
		inline  Abstract_Na_s_gate* sgate2() { return (Abstract_Na_s_gate*) gate2(); }
	};

	class Blended_Na_channel : public Abstract_Na_channel {
	
	public:
		// Constructors and destructor
		Blended_Na_channel(
			Number		gSpVal=0,					// specific conductance value
			Number		blendRatio=0.5,				// prox-distal blend ratio
			bool		sGateDisabled=false,		// s-gate disabled or not
			Number		sGateValue=0.5);			// fixed s-gate value if disabled
		virtual ~Blended_Na_channel() {}

		// Control current s gate status
		virtual bool	sGateDisabled()				{ return _blendedSGate->gateDisabled(); }
		virtual void	sGateDisabled(bool status)	{ _blendedSGate->gateDisabled(status); }

		virtual Number	sGateDisabledValue()		{ return _blendedSGate->disabledValue(); }
		virtual void	sGateDisabledValue(Number x) { _blendedSGate->disabledValue(x); }

	protected:
		Blended_Na_s_gate*		_blendedSGate;

		// Reversal potential for Na+
		virtual Number Vrev() { return _Vrev; }

	protected:
		static const Number		_Vrev;
	};

	// Soma Na channel ------------------------------------------------

	class Soma_Na_m_gate : public EnergyBarrierTabGate {

	public:
		// Constructors and destructor
		Soma_Na_m_gate() {}
		virtual ~Soma_Na_m_gate() {}

		// Estimated temperature sensitivity
		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return	 4; }

		// Order 3 gate for vhalf=-30mV,k=6.9mV (Colbert & Pan)
		// This is very close to values from Magee & Johnston.
		virtual Number	Vhalf()			{return -42.9*UOM::mV; }
		virtual Number	slope()			{return  8.4*UOM::mV; }

		// Time constants (see Costa)
		virtual Number	tauMax()		{return 0.2*UOM::msec; }
		virtual Number	tauMin()		{return 0.05*UOM::msec; }
		virtual Number	gamma()			{return 0.5f; }

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char**	stateLabels() {
			static const char* sl[] = { "m" }; return sl; }

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};

	class Soma_Na_s_gate : public Abstract_Na_s_gate {

	public:
		// Constructors and destructor
		Soma_Na_s_gate(
			bool isDisabled=false,	// set gateDisabled on or off
			Number dval=0.5f)		// set default disabled value
			: Abstract_Na_s_gate(isDisabled,dval) {}

		virtual ~Soma_Na_s_gate() {}

		// Voltage sensitivity from Colbert & Pan
		virtual Number	Vhalf()			{return -66*UOM::mV; }
		virtual Number	slope()			{return -5.3*UOM::mV; }

		// Time constant. Entry into slow inactivation is reduced
		// for somatic (and also proximal) channels but recovery
		// times are the same as for dendrites. This is modeled
		// by making the time constant less depedent on voltage.
		virtual Number	tauMax()		{return  1300*UOM::msec; }
		virtual Number	tauMin()		{return  800*UOM::msec; }

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static  AlphaBetaEntry*		_abTable;
	};

	class Soma_Na_channel : public Abstract_Na_channel {
	
	public:
		// Constructors and destructor
		Soma_Na_channel(
			Number		gSpVal=0,					// specific conductance value
			bool		sGateDisabled=false,		// s-gate disabled or not
			Number		sGateValue=0.5);			// fixed s-gate value if disabled
		virtual ~Soma_Na_channel() {}

		// Reversal potential for Na+
		virtual Number Vrev() { return _Vrev; }

	protected:
		static const Number		_Vrev;
	};

	// Axon Na channel ------------------------------------------------

	class Axon_Na_m_gate : public EnergyBarrierTabGate {

	public:

		// Constructors and destructor
		Axon_Na_m_gate() {}
		virtual ~Axon_Na_m_gate() {}

		// Estimated temperature sensitivity
		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return	 4; }

		// Order 3 gate for Vhalf=-38.4mV, k=6.0mV (Colbert & Pan)
		virtual Number	Vhalf()			{return -48.4*UOM::mV; }
		virtual Number	slope()			{return  7.3*UOM::mV; }

		// Time constants typical of HH axon measurements and models.
		// See fit by Colbert & Pan to HH formalism.
		virtual Number	tauMax()		{return 0.5*UOM::msec; }
		virtual Number	tauMin()		{return 0.05*UOM::msec; }
		virtual Number	gamma()			{return 0.5f; }

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char** stateLabels() { 
			static const char* sl[] = { "m" }; return sl; }

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};

	class Axon_Na_h_gate : public EnergyBarrierTabGate {

	public:
		// Constructors and destructor
		Axon_Na_h_gate() {}
		virtual ~Axon_Na_h_gate() {}

		// Values from Colbert & Pan
		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return	 2; }

		virtual Number	Vhalf()			{return -69*UOM::mV; }
		virtual Number	slope()			{return -5.3*UOM::mV; }

		// Time constants similar to Colbert & Pan fit of currents
		virtual Number	tauMax()		{return 6*UOM::msec; }
		virtual Number	tauMin()		{return 0.4*UOM::msec; }
		virtual Number	gamma()			{return 0.5f; }

		// State vector label functions
		virtual const char*	componentName() {return "Na"; }
		virtual const char** stateLabels() { 
			static const char* sl[] = { "h" }; return sl; }

	protected:
		virtual AlphaBetaEntry** pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};

	class Axon_Na_channel : public M3HIonChannel {
	
	public:
		// Constructors and destructor
		Axon_Na_channel(Number gSpVal=0);
		virtual ~Axon_Na_channel() {}

		// Reversal potential for Na+
		virtual Number Vrev() { return _Vrev; }

	protected:
		static const Number		_Vrev;
	};


	// Persistent Na channel ------------------------------------------

	class Persistent_Na_m_gate : public EnergyBarrierTabGate {

	public:

		// Constructors and destructor
		Persistent_Na_m_gate() {}
		virtual ~Persistent_Na_m_gate() {}

		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return	 3; } // assumed Q10

		// Voltage sensitivity (Magistretti & Alonso 1999 in situ)
		virtual Number	Vhalf()			{return -51.3*UOM::mV; }
		virtual Number	slope()			{return  4.0*UOM::mV; }

		// Time constant (see Magistretti & Alonso 2002)
		// These are based on decay and first latency times,
		// but obviously this model oversimplifies the kinetics.
		virtual Number	tauMax()		{return  18*UOM::msec; }
		virtual Number	tauMin()		{return  0.3*UOM::msec; }

		// State vector label functions
		virtual const char*	componentName() {return "NaP"; }
		virtual const char** stateLabels() { 
			static const char* sl[] = { "m" }; return sl; }

	protected:
		virtual AlphaBetaEntry**	pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};

	class Persistent_Na_h_gate : public EnergyBarrierTabGate {

	public:

		// Constructors and destructor
		Persistent_Na_h_gate() {}
		virtual ~Persistent_Na_h_gate() {}

		virtual Number	ratedTempC()	{return  22; }
		virtual Number	Q10()			{return	 1; } // unknown Q10

		// Voltage sensitivity (see Magistretti & Alonso 1999)
		virtual Number	Vhalf()			{return -48.4*UOM::mV; }
		virtual Number	slope()			{return -10.0*UOM::mV; }

		// Time constant (see Magistretti & Alonso 1999)
		virtual Number	tauMax()		{return  6.0*UOM::sec; }
		virtual Number	tauMin()		{return  2.0*UOM::sec; }
		virtual Number	gamma()			{return  0.2f; }

		// State vector label functions
		virtual const char*	componentName() {return "NaP"; }
		virtual const char**	stateLabels() { 
			static const char* sl[] = { "h" }; return sl; }

	protected:
		virtual AlphaBetaEntry**	pAlphaBetaTable() { return &_abTable; }

	private:
		static AlphaBetaEntry*		_abTable;
	};

	class Persistent_Na_channel : public M1HIonChannel {

	public:

		// Constructors and destructor
		Persistent_Na_channel(Number gSpVal);
		virtual ~Persistent_Na_channel() {}

		// Reversal potential for Na+
		virtual Number Vrev() { return _Vrev; }

	protected:
		static const Number			_Vrev;
	};

};

#endif // #ifndef __IONCHAN_NA_BAKER_2003_H_