     with ConsAKD     ; use ConsAKD;
     with CursAKD     ; use CursAKD;
     with DOS_011_Plot; use DOS_011_Plot;
     with FloaAKD     ; use FloaAKD;
     with HHNM        ; use HHNM;
     with MathAKD     ; use MathAKD;
     with MatrAK      ; use MatrAK;
     with TTY         ;

     procedure Coupled is
     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
       Somas : array ( 1..2 ) of Soma_Type;
       Status : Status_Type;
       J_Stims : constant array ( Somas'range ) of float
	 := ( 1.0e-5, 2.0e-5 );
       X_Data : Vector_Type ( 0..79 ) := ( others => 0.0 );
       Y_Datas : array ( Somas'range ) of Vector_Type ( X_Data'range )
	 := ( others => ( others => 0.0 ) );
       Plot_Interval : constant natural := 200;
       Plot_Last : natural := Plot_Interval;
       Plot_Symbols : constant array ( Somas'range ) of character
	 := ( 'o', '*' );
       Spike_Counts : array ( Somas'range ) of natural := ( others => 0 );
       Is_Firings : array ( Somas'range ) of boolean := ( others => false);
       Time_Delta : constant float := Time_Delta_Default;
       Time : float := 0.0;
       Spike_Lasts : array ( Somas'range ) of float := ( others => 0.0 );
       ISIs        : array ( Somas'range ) of float := ( others => 0.0 );
       Command     : character;
       G_Syns      : array ( Somas'range ) of float := ( others => 0.0 );
       G_dt_Syns   : array ( Somas'range ) of float := ( others => 0.0 );
       Ks          : array ( Somas'range ) of float := ( others => 0.0 );
       Time_Peak   : constant float := 2.0e-3; -- seconds
       Delays      : array ( Somas'range ) of float := ( others => 0.0 );
       Neurotransmitter : float;
       Fixed_Delay : float := 2.0e-3;
     begin
       Fixed_Delay := Ask ( "Fixed Delay: ", Fixed_Delay );
       for Index in X_Data'range loop
	 X_Data ( Index ) := float ( Index );
       end loop;
       Ks ( 1 ) := 5.0e-5 * Exp ( 1.0 ) / Time_Peak;
       Ks ( 2 ) := 5.0e-5 * Exp ( 1.0 ) / Time_Peak;
       loop
	 for Soma in Somas'range loop
	   if Delays ( Soma ) <= 0.0 then
	     G_Syns ( Soma )    := 0.0;
	     G_dt_Syns ( Soma ) := 0.0;
	     Neurotransmitter := Ks ( Soma ) / Time_Delta;
	     Delays ( Soma ) := 1.0e99;
	   else
	     Neurotransmitter := 0.0;
	     Delays ( Soma ) := Delays ( Soma ) - Time_Delta;
	   end if;
	   Alpha ( G_Syns ( Soma ), G_dt_Syns ( Soma ),
	     Neurotransmitter,
	     Decay => 1.0 / Time_Peak, dt => Time_Delta );
	   Soma_HH ( Status, Somas ( Soma ),
	     J_Stims ( Soma )
	     + ( V_Na_Default - Somas ( Soma ).V_Memb ) * G_Syns ( Soma ),
	     Time_Delta => Time_Delta );
	   if Somas ( Soma ).V_Memb >= 0.0 then
	     if not Is_Firings ( Soma ) then
	       Is_Firings ( Soma ) := true;
	       Spike_Counts ( Soma ) := Spike_Counts ( Soma ) + 1;
	       ISIs ( Soma ) := Time - Spike_Lasts ( Soma );
	       Spike_Lasts ( Soma ) := Time;
	       if Soma /= Somas'last then
		 Delays ( Soma + 1 ) := Fixed_Delay;
	       else
		 Delays ( 1 ) := Fixed_Delay;
	       end if;
	     end if;
	   else
	     Is_Firings ( Soma ) := false;
	   end if;
	   if Plot_Last > Plot_Interval then
	     for Index in Y_Datas ( Soma )'range loop
	       if Index < Y_Datas ( Soma )'last then
		 Y_Datas ( Soma ) ( Index )
		   := Y_Datas ( Soma ) ( Index + 1 );
	       end if;
	     end loop;
	     Y_Datas ( Soma ) ( Y_Datas ( Soma )'last )
	       := Somas ( Soma ).V_Memb;
	   end if;
	 end loop;
	 if Plot_Last > Plot_Interval then
	   Plot_Last := 0;
	 else
	   Plot_Last := Plot_Last + 1;
	 end if;
	 if Plot_Last = 0 then
	   Clear_Screen;
	   for Soma in Somas'range loop
	     Plot_XY ( X_Data, Y_Datas ( Soma ), Plot_Symbols ( Soma ),
	       false, 0.0, 79.0, -0.100, +0.100 );
	     Move ( 24, ( Soma - 1 ) * 40 );
	     Put ( float ( Spike_Counts ( Soma ) ) / Time );
	     Put ( ISIs ( Soma ) );
	     Put ( Delays ( Soma )  );
	     Put ( G_Syns ( Soma ), Exp => 2 );
	   end loop;
	 end if;
	 if TTY.Char_Ready then
	   Command := TTY.Get ( No_Echo => true );
	   case Command is
	     when 'p'|'P' => Command := TTY.Get ( true ); -- pause
	     when 'q'|'Q' => exit;                        -- quit
	     when others  => TTY.Put ( ASCII.BEL );       -- error
	   end case;
	 end if;
	 Time := Time + Time_Delta;
       end loop;
     end Coupled;
