using System;
using System.Collections.Generic;
using MiMic.CsApi;
namespace MiMic.CsApi.LPC1769
{
	public class Memory:MiMicClass
	{
		private static void checkAlign(UInt32 v)
		{
			if(v%4!=0){
				throw new MiMicException("An alignment is not 32bit unit.");
			}
		}
		private Mcu _mcu;
		private UInt32 _base;
		public Memory(Mcu i_mcu,UInt32 i_base)
		{
			this._base=i_base;
			this._mcu=i_mcu;
		}
		private class NBgetValueseResult:NBUIntArrayResult
		{
			public NBgetValueseResult(MiMicRemoteMcuInterface.NBMiMicResult i_result):base(i_result)
			{
			}
			public override UInt32[] getValues()
			{
				if(!this.isDone){
					throw new MiMicException();
				}
				return this.result.stream.ToArray();
			}
		}
		private string BCF_read32(UInt32 i_addr,List<UInt32> i_db)
		{
			checkAlign(i_addr);
			string bc=LPCXpresso1769._BCF.READMEM;
			i_db.Add(this._base+i_addr);
			return bc;
		}			
		public UInt32[] read32(UInt32 i_addr)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_read32(i_addr,db);
			MiMicRemoteMcuInterface.MiMicResult ret=this._mcu.callMiMicWithCheck(bc+LPCXpresso1769._BCF.END,db);
			return ret.stream.ToArray();
		}
		public NBUIntArrayResult read32NB(UInt32 i_addr)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_read32(i_addr,db);
			return new NBgetValueseResult(this._mcu.callMiMicNB(bc+LPCXpresso1769._BCF.END,db));
		}
		//
		//read32(UInt32[] i_addr,List<UInt32> i_db)
		//
		
		private string BCF_read32(UInt32[] i_addr,List<UInt32> i_db)
		{
			string bc="";
			for(int i=0;i<i_addr.Length;i++){
				checkAlign(i_addr[i]);
				bc+=LPCXpresso1769._BCF.getMem(this._base+i_addr[i],i_db);
			}
			return bc;
		}				
		public UInt32[] read32(UInt32[] i_addr)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_read32(i_addr,db);
			MiMicRemoteMcuInterface.MiMicResult ret=this._mcu.callMiMicWithCheck(bc+LPCXpresso1769._BCF.END,db);
			return ret.stream.ToArray();
		}
		public NBUIntArrayResult read32NB(UInt32[] i_addr)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_read32(i_addr,db);
			return new NBgetValueseResult(this._mcu.callMiMicNB(bc+LPCXpresso1769._BCF.END,db));
		}
		//
		//read32(UInt32 i_addr,UInt32 i_bytes,List<UInt32> i_db)
		//
		
		private string BCF_read32(UInt32 i_addr,UInt32 i_bytes,List<UInt32> i_db)
		{
			checkAlign(i_addr);
			checkAlign(i_bytes);
			UInt32 l=i_bytes/4;
			string bc="";
			for(UInt32 i=0;i<l;i++){
				bc+=LPCXpresso1769._BCF.READMEM;
				i_db.Add(this._base+i_addr+i*4);
			}
			return bc;
		}
		public UInt32[] read32(UInt32 i_addr,UInt32 i_bytes)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_read32(i_addr,i_bytes,db);
			MiMicRemoteMcuInterface.MiMicResult ret=this._mcu.callMiMicWithCheck(bc+LPCXpresso1769._BCF.END,db);
			return ret.stream.ToArray();
		}
		public NBUIntArrayResult read32NB(UInt32 i_addr,UInt32 i_bytes)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_read32(i_addr,i_bytes,db);
			return new NBgetValueseResult(this._mcu.callMiMicNB(bc+LPCXpresso1769._BCF.END,db));
		}
		//
		//write32(UInt32 i_addr,UInt32 i_value,List<UInt32> i_db)
		//
		 
		private string BCF_write32(UInt32 i_addr,UInt32 i_value,List<UInt32> i_db)
		{
			checkAlign(i_addr);
			string bc="";
			bc+=LPCXpresso1769._BCF.setMem(this._base+i_addr,i_value,i_db);
			return bc;
		}
		public void write32(UInt32 i_addr,UInt32 i_value)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_write32(i_addr,i_value,db);
			this._mcu.callMiMicWithCheck(bc+LPCXpresso1769._BCF.END,db);
		}
		public NBResult write32NB(UInt32 i_addr,UInt32 i_value)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_write32(i_addr,i_value,db);
			return new NBResult(this._mcu.callMiMicNB(bc,db));
		}

		//
		//write32(UInt32 i_addr,UInt32[] i_value,List<UInt32> i_db)
		//
		
		private string BCF_write32(UInt32 i_addr,UInt32[] i_value,List<UInt32> i_db)
		{
			checkAlign(i_addr);
			string bc="";
			for(UInt32 i=0;i<i_value.Length;i++){
				bc+=LPCXpresso1769._BCF.setMem(this._base+i_addr+i*4,i_value[i],i_db);
			}
			return bc;
		}
		public void write32(UInt32 i_addr,UInt32[] i_value)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_write32(i_addr,i_value,db);
			this._mcu.callMiMicWithCheck(bc+LPCXpresso1769._BCF.END,db);
		}
		public NBResult write32NB(UInt32 i_addr,UInt32[] i_value)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_write32(i_addr,i_value,db);
			return new NBResult(this._mcu.callMiMicNB(bc+LPCXpresso1769._BCF.END,db));
		}
		
		//
		//write32(UInt32[] i_addr,UInt32[] i_value,List<UInt32> i_db)
		//		
		
		private string BCF_write32(UInt32[] i_addr,UInt32[] i_value,List<UInt32> i_db)
		{
			if(i_addr.Length!=i_value.Length){
				throw new MiMicException();
			}
			string bc="";
			for(var i=0;i<i_value.Length;i++){
				checkAlign(i_addr[i]);
				bc+=LPCXpresso1769._BCF.setMem(this._base+i_addr[i],i_value[i],i_db);
			}
			return bc;
		}
		public void write32(UInt32[] i_addr,UInt32[] i_value)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_write32(i_addr,i_value,db);
			this._mcu.callMiMicWithCheck(bc+LPCXpresso1769._BCF.END,db);
		}
		public NBResult write32NB(UInt32[] i_addr,UInt32[] i_value)
		{
			List<UInt32> db=new List<UInt32>();
			string bc=this.BCF_write32(i_addr,i_value,db);
			return new NBResult(this._mcu.callMiMicNB(bc+LPCXpresso1769._BCF.END,db));
		}
		
	}
}

