library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
	 entity VGA_Top is
    Port ( R : out  STD_LOGIC;
           G : out  STD_LOGIC;
           B : out  STD_LOGIC;
           Clk : in  STD_LOGIC;
           HS : out  STD_LOGIC;
           VS : out  STD_LOGIC;
			  button : in  STD_LOGIC;
			  reset : in  STD_LOGIC;
			  LED : out  STD_LOGIC;
			  Enables : out  STD_LOGIC_VECTOR(3 downto 0);
			  Segments : out  STD_LOGIC_VECTOR(6 downto 0);
			  inColor : in  STD_LOGIC_VECTOR (2 downto 0);
			  MoveUp : in  STD_LOGIC;
			  MoveDown : in  STD_LOGIC;
			  MoveLeft : in  STD_LOGIC;
			  MoveRight : in  STD_LOGIC;
			  MoveP1 : in  STD_LOGIC;
			  MoveP2 : in  STD_LOGIC);
end VGA_Top;
architecture Behavioral of VGA_Top is
COMPONENT Debouncer
	PORT(
		Clk : IN std_logic;
		Button : IN std_logic;
		Dout : OUT std_logic);
END COMPONENT;
COMPONENT Bresenhamer
	PORT(
		X1 : IN std_logic_vector(9 downto 0);
		Y1 : IN std_logic_vector(8 downto 0);
		X2 : IN std_logic_vector(9 downto 0);
		Y2 : IN std_logic_vector(8 downto 0);
		Clk : IN std_logic;
		StartDraw : IN std_logic;
		WriteEnable : OUT std_logic;
		SS : OUT STD_LOGIC_VECTOR (3 downto 0);
		X : OUT std_logic_vector(9 downto 0);
		Y : OUT std_logic_vector(8 downto 0);
		Reset : in  STD_LOGIC);
END COMPONENT;
Component Synchronizer is
    Port ( R : out  STD_LOGIC;
           G : out  STD_LOGIC;
           B : out  STD_LOGIC;
           HS : out  STD_LOGIC;
           VS : out  STD_LOGIC;
           Clk : in  STD_LOGIC;
			  dataIn : in  STD_LOGIC_VECTOR (2 downto 0);
			  AddressX : out  STD_LOGIC_VECTOR (9 downto 0);
			  AddressY : out  STD_LOGIC_VECTOR (8 downto 0));
end Component;
Component FrameBuffer is
    Port ( inX : in  STD_LOGIC_VECTOR (9 downto 0);
           inY : in  STD_LOGIC_VECTOR (8 downto 0);
           outX : in  STD_LOGIC_VECTOR (9 downto 0);
           outY : in  STD_LOGIC_VECTOR (8 downto 0);
           outColor : out  STD_LOGIC_VECTOR (2 downto 0);
           inColor : in  STD_LOGIC_VECTOR (2 downto 0);
           BufferWrite : in  STD_LOGIC;
           Clk : in  STD_LOGIC);
end Component;
COMPONENT SevenSegment
	PORT(	Clk : IN std_logic;
			data : IN std_logic_vector(15 downto 0);
			Enables : OUT std_logic_vector(3 downto 0);
			Segments : OUT std_logic_vector(6 downto 0));
END COMPONENT;
COMPONENT Pointer
	Generic (initX : STD_LOGIC_VECTOR (9 downto 0);
				initY : STD_LOGIC_VECTOR (8 downto 0));
	PORT(	MoveUp : IN std_logic;
			MoveDown : IN std_logic;
			MoveLeft : IN std_logic;
			MoveRight : IN std_logic;
			Move : IN std_logic;
			Clk : IN std_logic;
			X : OUT std_logic_vector(9 downto 0);
			Y : OUT std_logic_vector(8 downto 0);
			syncX : IN std_logic_vector(9 downto 0);
			syncY : IN std_logic_vector(8 downto 0);
			Here : OUT std_logic);
END COMPONENT;
COMPONENT FreqDiv
	PORT(	Clk : IN std_logic;
			Clk2 : OUT std_logic);
END COMPONENT;
signal Adx,GPU_X : STD_LOGIC_VECTOR (9 downto 0);
signal Ady,GPU_Y : STD_LOGIC_VECTOR (8 downto 0);
signal data : STD_LOGIC_VECTOR (2 downto 0);
signal GIM : STD_LOGIC_VECTOR (22 downto 0);
signal GPU_COLOR_TO_BUFFER : STD_LOGIC_VECTOR (2 downto 0);
signal BufferWrite : STD_LOGIC;
signal Dout : STD_LOGIC;
signal SS : STD_LOGIC_VECTOR (3 downto 0);
signal Clk2 : STD_LOGIC;
signal P1Region,p2Region : STD_LOGIC;
signal Rt,Gt,Bt : STD_LOGIC;
signal X1,X2 : STD_LOGIC_VECTOR (9 downto 0);
signal Y1,Y2 : STD_LOGIC_VECTOR (8 downto 0);
begin
ins_FrameBuffer : FrameBuffer PORT MAP (
	inX => GPU_X,
   inY => GPU_Y,
   outX => Adx,
   outY => Ady,
   outColor => data,
   inColor => inColor,
   BufferWrite => BufferWrite,
   Clk => Clk);
ins_Synchronizer : Synchronizer PORT MAP (
	 R => Rt,
    G => Gt,
    B => Bt,
    HS => HS,
    VS => VS,
    Clk => Clk,
	 dataIn => data,
	 AddressX => Adx,
	 AddressY => Ady);
Inst_Debouncer: Debouncer PORT MAP(
	Clk => Clk,
	Button => Button,
	Dout => Dout);
Inst_Bresenhamer: Bresenhamer PORT MAP(
	WriteEnable => BufferWrite,
	X => GPU_X,
	Y => GPU_Y,
	X1 => X1,
	Y1 => Y1,
	X2 => X2,
	Y2 => Y2,
	Clk => Clk,
	SS => SS,
	Reset => reset,
	StartDraw => Dout);

LED <= BufferWrite;

R <= Rt when (P1Region='0' and P2Region='0') else not Rt;

G <= Gt when (P1Region='0' and P2Region='0') else not Gt;

B <= Bt when (P1Region='0' and P2Region='0') else not Bt;

Inst_SevenSegment: SevenSegment PORT MAP(
	Clk => Clk,
	Enables => Enables,
	Segments => Segments,
	data(3 downto 0) => SS,
	data(15 downto 4) => "000000000000");

Inst_Pointer1: Pointer
	GENERIC MAP (initX => "0000000100",
					 initY => "011110000")
	PORT MAP(
	MoveUp => MoveUp,
	MoveDown => MoveDown,
	MoveLeft => MoveLeft,
	MoveRight => MoveRight,
	Move => MoveP1,
	Clk => Clk2,
	Here => P1Region,
	X => X1,
	Y => Y1,
	syncX => Adx,
	syncY => Ady);

Inst_FreqDiv: FreqDiv PORT MAP(
	Clk => Clk,
	Clk2 => Clk2);

Inst_Pointer2: Pointer
	GENERIC MAP (InitX => "1001111000",
					 InitY => "011110000")
	PORT MAP(
	MoveUp => MoveUp,
	MoveDown => MoveDown,
	MoveLeft => MoveLeft,
	MoveRight => MoveRight,
	Move => MoveP2,
	Clk => Clk2,
	Here => P2Region,
	X => X2,
	Y => Y2,
	syncX => Adx,
	syncY => Ady);

end Behavioral;
