package ga050426;

class SDEntries {
	String name;
	int base;
	int length;
	int number;
	String descr = null;
	static int staticNumber = 0; // Segment definition counter

	SDEntries prev = null, next = null;

	SDEntries(String name, int base, SDEntries prev, SDEntries next) {
		this.name = name;
		this.base = base;
		this.number = ++staticNumber;
		if (name.contains("dat"))
			this.descr = "RW";
		else if (name.contains("txt"))
			this.descr = "RE";
		else if (name.contains("bss"))
			this.descr = "RW";
		this.prev = prev;
		this.next = next;
	}

	void setDescr(String descr) {
		this.descr += descr;
	}
}

public class Segments {
	public static String currentSegmentName = null; // Need for dat txt...
	public static SDEntries currentSegmentReference = null;
	public static int currentSegmentNumber = 0;
	public static Segments instance = new Segments();
	public int defs = 0;
	private SDEntries head = null, tail = null;

	public void add(String name, int startAddr){
		if (tail != null) {
			tail.length = (int) (startAddr - tail.base);
			if(tail.length!=0 && !tail.name.equals("bss"))tail.setDescr("P");
			tail = tail.next = new SDEntries(name, startAddr, tail, null);
		} 
		else{
			tail = head = new SDEntries(name, startAddr, tail, null);
			if(tail.length!=0 && !tail.name.equals("bss"))tail.setDescr("P");
		}
		currentSegmentReference = tail;
		currentSegmentName = name;
		currentSegmentNumber = tail.number;
		defs++;
	}

	public void end(int addr) {
		if (currentSegmentReference == null)
			return;
		currentSegmentReference.length = (int) (addr - currentSegmentReference.base);
		if(currentSegmentReference.length!=0 && !currentSegmentReference.name.equals("bss"))currentSegmentReference.setDescr("P");
	}
	
	public String getSegs() { // for Data Section
		StringBuffer buf = new StringBuffer(String.format("#Data (hex)%n"));
		for (SDEntries cur = head; cur != null; cur = cur.next) {
			if (cur.descr.contains("P")) {
				for (int p = cur.base; p < cur.base + cur.length; p++)
					buf.append(String.format("%02x ", DataSection.buff.get(p)));
				buf.append("\n");
			}
		}
		return new String(buf);
	}

	public String getDefs() {
		StringBuffer buf = new StringBuffer(String.format("#Segments (hex)%n"));
		for (SDEntries cur = head; cur != null; cur = cur.next) {
			buf.append(String.format(".%-5s\t%x\t%x\t%-3s%n", cur.name,
					cur.base, cur.length, cur.descr));
		}
		return new String(buf);
	}
}
