package pp.iloc.eval;

import java.util.Arrays;

import pp.s1184725.boppi.ToolChain;

/** Simulated memory. */
public class Memory {
	/** The default size of the memory, in number of bytes. */
	public final static int DEFAULT_SIZE = 10000;
	/** The memory array. */
	private byte[] mem = new byte[DEFAULT_SIZE];

	/** Reinitialises the memory to a certain size. */
	public void setSize(int size) {
		this.mem = new byte[size];
	}

	/** Sets a location in memory to a given value. */
	public void set(int loc, byte value) {
		this.mem[loc] = value;
	}

	/** 
	 * Returns the value at a given memory location.
	 * The value is 0 if the location was never accessed before. 
	 */
	public byte get(int loc) {
		return this.mem[loc];
	}

	/** Returns the size of the used memory. */
	public int size() {
		return this.mem.length;
	}

	/** Removes all values from the memory. */
	public void clear() {
		Arrays.fill(this.mem, (byte) 0);
	}

	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
//		boolean wasEmpty = false;
//		for (int i = 0; i < size(); i++) {
////			if (get(i) == 0) {
////				continue;
////			}
////			if (result.length() > 0) {
////				result.append(", ");
////			}
////			result.append(i);
////			result.append(":");
////			result.append(String.format("%02X", get(i) & 0xFF));
//			if (i % 32 == 0) {
//				boolean anyNonzero = false;
//				
//				for (int j = i; j < i+32 && j < size(); j++)
//					if ((get(j) & 0xFF) != 0) {
//						anyNonzero = true;
//						break;
//					}
//				
//				if (!anyNonzero) {
//					if (!wasEmpty)
//						result.append("\n. . .");
//					wasEmpty = true;
//					
//					i += 31;
//					continue;
//				}
//				else
//					wasEmpty = false;
//				
//				result.append("\n");
//				result.append(String.format("%08x  ", i));
//			}
//			if ((get(i) & 0xFF) != 0)
//				result.append(String.format("%02X", get(i) & 0xFF));
//			else
//				result.append("..");
//			if (i % 4 == 3)
//				result.append(" ");
//		}
		
		int loc = 4;
		
		System.err.flush();
		
		while (loc != 0 && loc < ToolChain.machine.getReg("brk")) {
			int size = ToolChain.machine.load(loc+4);
			int nloc = ToolChain.machine.load(loc);
			
			if (!(size == 0 && nloc == 0)) {
			result.append(String.format("0x%05x  ", loc+8));
			
			if ((nloc >= ToolChain.machine.load(0) && nloc > loc) || nloc == 0)
				result.append("   free");
			else
				result.append(String.format("% 2d ref ", ToolChain.machine.load(loc)));
			
			for(int i = 0; i < size && i < 40; i += 4) {
				if (ToolChain.machine.load(loc+8+i) == 0)
					result.append("........");
				else
					result.append(String.format("%8x", ToolChain.machine.load(loc+8+i)).replace(" ", "."));
				result.append(" ");
			}
			result.append(size > 40 ? "...\n" : "\n");
			}
			loc += size+8;
		}

		return result.toString();
	}
}
