-- Note: Record is a keyword, so am using RecordX

library ieee;
use ieee.std_logic_1164.all;
entity ANS_MACH2 is port(
	Clk, DialTone:					in std_logic;
	Ring, EndGreeting, EndMessage:	in std_logic;
	Answer, Play, RecordX:			out std_logic);
end ANS_MACH2;

architecture behavior of ANS_MACH2 is
	type States is (Waiting, Playing, Recording);
attribute enum_encoding of States: type is "00 01 11";
	signal PreState, NextState:	States;
	signal Idle, BeginPlay, RunPlayer: 		std_logic;
	signal BeginRecord, RunRecorder, Done: 	std_logic;
	signal Outs:							std_logic_vector(2 downto 0);
begin

Idle <= DialTone and not Ring;
BeginPlay <= Ring;
RunPlayer <= not EndGreeting and not DialTone;
Done <= EndMessage or DialTone;
RunRecorder <= not EndMessage and not DialTone;

Answer <= Outs(2); Play <= Outs(1); RecordX <= Outs(0);

NEW_STATE: process(Clk) begin
	if RISING_EDGE(Clk) then
		case PreState is
			when Waiting =>	if BeginPlay='1' then NextState<=Playing;
					else NextState<=Waiting;
				end if;
				Outs <= "000";
			when Playing => if Idle='1' then NextState<=Waiting;
					elsif BeginRecord='1' then NextState<=Recording;
					else NextState<=Playing;
				end if;
				Outs <= "110";
			when Recording => if (Done='1') then
					NextState<=Waiting; else NextState<=Recording;
				end if;
				Outs <= "101";
			when others =>	NextState<=Waiting;
		end case;
	end if;
end process NEW_STATE;

UPDATE_STATE: process (Clk) begin
	if RISING_EDGE(Clk) then
		PreState <= NextState;
	end if;
end process UPDATE_STATE;

end behavior;
