
module resize (
	input clk48, input rst, 
	input[15:0] i_s_oldnew_Rows, input[15:0] i_s_oldnew_Cols, 
	input[9:0] i_old_numRows, input[9:0] i_old_numCols,    
	input[9:0] i_new_numRows, input[9:0] i_new_numCols,
	input imageloaded,		 
	input readdone, input writedone,
	output done
	);			   
	
	
	// registers to cache the input values when imageloaded goes high
	reg[15:0] s_oldnew_Rows; 
	reg[15:0] s_oldnew_Cols;
	reg[9:0] old_numRows;
	reg[9:0] old_numCols;
	reg[9:0] new_numRows;
	reg[9:0] new_numCols;
	
	// states
	reg [2:0] state;
	reg [2:0] nextstate;
	parameter reset = 0, loop1 = 1, loop2 = 2, read = 3, write = 4, endloop2 = 5, endloop1 = 6, donestate = 7;	 
	
	parameter shiftedby = 5;
	
	reg [15:0] s_cur_oldRow;
	reg [15:0] s_cur_oldCol;						 
	wire [15:0] cur_oldRow;
	wire [15:0] cur_oldCol;
	assign cur_oldRow = s_cur_oldRow >> shiftedby;
	assign cur_oldCol = s_cur_oldCol >> shiftedby; 
	
	reg doneflag;
	assign done = doneflag;
	
	reg [9:0] r;  
	reg [9:0] c;
	
	reg [19:0] i;	 // new addr					  
	reg [19:0] addr; // old addr 	   
	
	
	// should all be synthesized to wires
	reg nextdoneflag;
	reg [19:0] nexti;
	reg [9:0] nextr;
	reg [9:0] nextc;
	reg [15:0] nexts_oldnew_Rows;
	reg [15:0] nexts_oldnew_Cols;
	reg [9:0] nextold_numRows;
	reg [9:0] nextold_numCols;
	reg [9:0] nextnew_numRows;
	reg [9:0] nextnew_numCols;
	reg [19:0] nextaddr;
	reg [15:0] nexts_cur_oldRow;
	reg [15:0] nexts_cur_oldCol;
	
	always @(posedge clk48) begin 
		if (rst) begin
			state <= reset;
		end else begin
			state <= nextstate;	 
			i <= nexti;
			r <= nextr;
			c <= nextc;
			s_oldnew_Rows <= nexts_oldnew_Rows; 
			s_oldnew_Cols <= nexts_oldnew_Cols;
			old_numRows <= nextold_numRows;
			old_numCols <= nextold_numCols;
			new_numRows <= nextnew_numRows;
			new_numCols <= nextnew_numCols;
			addr <= nextaddr;
			s_cur_oldRow <= nexts_cur_oldRow;
			s_cur_oldCol <= nexts_cur_oldCol;
			doneflag <= nextdoneflag;
		end	
	end

	
	
	always @(*) begin	
		
		// defaults
		nextdoneflag = 0;  
		nexti = i;
		nextr = r;
		nextc = c;
		nexts_oldnew_Rows = s_oldnew_Rows; 
		nexts_oldnew_Cols = s_oldnew_Cols;
		nextold_numRows = old_numRows;
		nextold_numCols = old_numCols;
		nextnew_numRows = new_numRows;
		nextnew_numCols = new_numCols;
		nextaddr = addr;
		nexts_cur_oldRow = s_cur_oldRow;
		nexts_cur_oldCol = s_cur_oldCol;		
		
		case(state)
			reset: begin
				nexts_cur_oldRow = s_oldnew_Rows >> 1;
				nexti = 0;
				nextr = 0;	 
				nextstate = (imageloaded) ? loop1 : reset;
			end
			loop1: begin	
				nexts_oldnew_Rows = i_s_oldnew_Rows; 
				nexts_oldnew_Cols = i_s_oldnew_Cols;
				nextold_numRows = i_old_numRows;
				nextold_numCols = i_old_numCols;
				nextnew_numRows = i_new_numRows;
				nextnew_numCols = i_new_numCols;
				nexts_cur_oldCol = s_oldnew_Cols >> 1;
				nextc = 0;							   
				nextstate = loop2;
			end
			loop2: begin
				nextaddr = cur_oldCol + (old_numCols * cur_oldRow);
				nextstate = read;
			end
			read: begin			 
				nextstate = (readdone) ? write : read;
			end
			write: begin							  
				nextstate = (writedone) ? endloop2 : write;
			end
			endloop2: begin
				nexts_cur_oldCol = s_cur_oldCol + s_oldnew_Cols;
				nexti = i + 1;
				nextc = c + 1;								   
				nextstate = (c < new_numCols) ? loop2 : endloop1;
			end
			endloop1: begin		
				nexts_cur_oldRow = s_cur_oldRow + s_oldnew_Rows;
				nextr = r + 1;										 
				nextstate = (r < new_numRows) ? loop2 : donestate;
			end
			donestate: begin
				nextdoneflag = 1;	  							 
				nextstate = donestate;  	// will want to modify this so that it doesn't stay in this state forever
			end
		endcase				  
	end
	
endmodule
