package org.eclipse.cdt.debug.mi.core.cdi.model;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MIFormat;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.debug.mi.core.cdi.MI2CDIException;
import org.eclipse.cdt.debug.mi.core.cdi.MemoryManager;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIDataWriteMemory;
import org.eclipse.cdt.debug.mi.core.output.MIDataReadMemoryInfo;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.cdt.debug.mi.core.output.MIMemory;

/**
 */
public class MemoryBlock extends CObject implements ICDIMemoryBlock {

	MIDataReadMemoryInfo mem;
	String expression;
	boolean frozen;
	boolean dirty;

	public MemoryBlock(ICDITarget target, String exp, MIDataReadMemoryInfo info) {
		super(target);
		expression = exp;
		mem = info;
		frozen = true;
	}

	/**
	 * @return the expression use to create the block.
	 */
	public String getExpression() {
		return expression;
	}

	/**
	 * Reset the internal MIDataReadMemoryInfo.
	 */
	public void setMIDataReadMemoryInfo(MIDataReadMemoryInfo m) {
		mem = m;
	}

	/**
	 * @return the internal MIDataReadMemoryInfo.
	 */
	public MIDataReadMemoryInfo getMIDataReadMemoryInfo() {
		return mem;
	}

	/**
	 * @return true if any address in the array is within the block.
	 */
	public boolean contains(Long[] adds) {
		for (int i = 0; i < adds.length; i++) {
			if (contains(adds[i])) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @return true if the address is within the block.
	 */
	public boolean contains(Long addr) {
		long start = getStartAddress();
		long length = getLength();
		if (start <= addr.longValue() && addr.longValue() <= start + length) {
			return true;
		}
		return false;
	}

	/**
	 * Use by the EventManager to check fire events when doing refresh().
	 */
	public boolean isDirty() {
		return dirty;
	}

	/**
	 * Use by the EventManager to check fire events when doing refresh().
	 */
	public void setDirty(boolean d) {
		dirty = d;
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#getBytes()
	 */
	public byte[] getBytes() throws CDIException {
		MIMemory[] miMem = mem.getMemories();
		List aList = new ArrayList();
		for (int i = 0; i < miMem.length; i++) {
			long[] data = miMem[i].getData();
			for (int j = 0; j < data.length; j++) {
					aList.add(new Long(data[j]));
			}
		}
		byte[] bytes = new byte[aList.size()];
		for (int i = 0; i < aList.size(); i++) {
			Long l = (Long)aList.get(i);
			bytes[i] = l.byteValue();
		}
		return bytes;
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#refresh()
	 */
	public void refresh() throws CDIException {
		MemoryManager mgr = (MemoryManager)getTarget().getSession().getMemoryManager();
		setDirty(true);
		Long[] addresses = mgr.update(this, null);
		// Check if this affects other blocks.
		if (addresses.length > 0) {
			MemoryBlock[] blocks = mgr.listMemoryBlocks();
			for (int i = 0; i < blocks.length; i++) {
				if (! blocks[i].equals(this) && blocks[i].contains(addresses)) {
					blocks[i].setDirty(true);
					mgr.update(blocks[i], null);
				}
			}
		}
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#getLength()
	 */
	public long getLength() {
		return mem.getTotalBytes();
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#getStartAddress()
	 */
	public long getStartAddress() {
		return mem.getAddress();
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#isFrozen()
	 */
	public boolean isFrozen() {
		return frozen;
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#setFrozen(boolean)
	 */
	public void setFrozen(boolean frozen) {
		this.frozen = frozen;
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#setValue(long, byte[])
	 */
	public void setValue(long offset, byte[] bytes) throws CDIException {
		if (offset >= getLength() || offset + bytes.length > getLength()) {
			throw new CDIException("Bad Offset");
		}
		Session session = (Session)getTarget().getSession();
		MISession mi = session.getMISession();
		CommandFactory factory = mi.getCommandFactory();
		for (int i = 0; i < bytes.length; i++) {
			long l = new Byte(bytes[i]).longValue() & 0xff;
			String value = "0x" + Long.toHexString(l);
			MIDataWriteMemory mw = factory.createMIDataWriteMemory(offset + i,
				expression, MIFormat.HEXADECIMAL, 1, value);
			try {
				mi.postCommand(mw);
				MIInfo info = mw.getMIInfo();
				if (info == null) {
					throw new CDIException("No answer");
				}
			} catch (MIException e) {
				throw new MI2CDIException(e);
			}
		}
		// If the assign was succesfull fire a MIChangedEvent() via refresh.
		refresh();
	}

}
