package sensicamJNI;

import java.util.HashMap;
import java.util.Map;

import sensicamJNI.SencamDef.sen_buflist;

public class SenbufDev {
	
	public static class DEVBUF_TRANSFER implements Cloneable {
	 long phys;
	 long size; //dword
	};

	public static class DEVBUF_ALLOC implements Cloneable {
	 long virt;
	 long phys;
	 long size; //dword
	};

	public static final int  WRITE_B               = 0;
	public static final int  WRITE_DONE_B          = 1;
	public static final int  QUEUED_B              = 2;
	public static final int  CANCEL_B              = 3;
	public static final int  EVENT_B               = 4;
	public static final int  EVENT_DONE_B          = 5;
	public static final int  MAPPED_B              = 6;
	public static final int  I4BYTES_B             = 7;
	public static final int  REMOVED_B             = 8;
	public static final int  NO_TRANS_CLOSE_B      = 9;
	public static final int  APP_BUFINUSE_B        = 11;
	public static final int  BURST_ERROR_B         = 12;
	public static final int  SIZE_ERROR_B          = 13;
	public static final int  PCI_ERROR_B           = 14;
	public static final int  TIMEOUT_ERROR_B       = 15;
	public static final int  EVENT_SET_B           = 27;
	public static final int  WRITE_PREPARED_B      = 28;
	public static final int  NOT_DRV_ALLOC_B       = 29;
	public static final int  LOCKED_B              = 30;
	public static final int  DRV_ALLOC_B           = 31;
	public static final int  ERROR_BITS            = 0x0000F000;
	public static final int  WRITE_PREPARED_BIT    = 0x10000000;
	public static final int  NOT_DRV_ALLOC_BIT     = 0x20000000;
	public static final int  LOCKED_BIT            = 0x40000000;
	public static final int  DRV_ALLOC_BIT         = 0x80000000;
	public static final int  APP_BUFINUSE_BIT      = 0x00000800;
	public static final int  APP_BITS              = 0x00000C00;


	public static class DEVBUF implements Cloneable	{
	 public int status;             //0
	                           //drv allocated          0x00xx0000
	                           //xx=buffernumber 0-128
	                           //or opencount for static buffers

	 public int counter;            //1 counter of images
	 public int isize;              //2 size of image buffer
	 public int rsize;              //3 size of bytes not transferred
	 public int map_com;            //4 HIWORD = mapcount, LOWORD = last comand
	 public int offset;             //5 offset of image buffer
	 public int allocsize;          //6 real allocation size
	 public int pagenum;            //7 numbers of allocated blocks
	 public int pagesize;           //8 size of allocated block
	 public int pagesize_last;      //9 size of last allocated block
	 public long picevent;     //10 picture in event wait_queue
	 public DEVBUF_ALLOC pagetab;    //table of vitual and physical addresses of device buffer  8
	 public DEVBUF_TRANSFER  transfertab;   //table of [physical addresses,size] of actual transfer  11
	 public DEVBUF_TRANSFER  ptrtransfer;   //actual pointer into transfertab 12
	 //pci_dev pci_dev;   //actual pci device for this buffer
	 public long pci_dev; //not sure what that is

	 public int SEN_BUF_STAT_WRITE(){         return ((status >> WRITE_B)&0x01); }
	 public int SEN_BUF_STAT_WRITE_DONE(){    return ((status >> WRITE_DONE_B)&0x01); }
	 public int SEN_BUF_STAT_QUEUED(){        return ((status >> QUEUED_B)&0x01); }
	 public int SEN_BUF_STAT_CANCELLED(){     return ((status >> CANCEL_B)&0x01); }
	 public int SEN_BUF_STAT_SELECT(){        return ((status >> EVENT_B)&0x01); }
	 public int SEN_BUF_STAT_SELECT_DONE(){   return ((status >> EVENT_DONE_B)&0x01); }
	 public int SEN_BUF_STAT_MAPPED(){        return ((status >> MAPPED_B)&0x01); }
	 public int SEN_BUF_STAT_FIRSTDMA(){      return ((status >> I4BYTES_B)&0x01); }
	 public int SEN_BUF_STAT_REMOVED(){       return ((status >> REMOVED_B)&0x01); }
	 public int SEN_BUF_STAT_ERROR(){         return  (status & ERROR_BITS); }
	 public int SEN_BUF_STAT_BURST_ERROR(){   return ((status >> BURST_ERROR_B)&0x01); }
	 public int SEN_BUF_STAT_SIZE_ERROR(){    return ((status >> SIZE_ERROR_B)&0x01); }
	 public int SEN_BUF_STAT_EVENT_ERROR(){   return ((status >> PCI_ERROR_B)&0x01); }
	 public int SEN_BUF_STAT_TIMEOUT_ERROR(){ return ((status >> TIMEOUT_ERROR_B)&0x01); }
	 public int SEN_BUF_OPENCOUNT(){  return ((status >> 16)&0xFF); } //only buffer devices
	 public int SEN_BUF_BUFNR(){      return ((status >> 16)&0xFF); }
	 
	 public int SEN_BUF_PICCOUNTER(){   return counter; }
	 public int SEN_BUF_ACT_SIZE(){     return isize; }
	 public int SEN_BUF_ACT_TRANSFER(){ return rsize; }
	 public int SEN_BUF_MAPCOUNT(){     return map_com>>16; }
	 public int SEN_BUF_ACT_OFFSET(){   return offset; }
	 public int SEN_BUF_TOTAL_SIZE(){   return allocsize; }
	 
	 @Override
		public String toString() {
			return "[BUF" + SEN_BUF_BUFNR() + ": +" +
					"WR" + SEN_BUF_STAT_WRITE() + ", " +
					"WD" + SEN_BUF_STAT_WRITE_DONE() + ", " +
					"Q" + SEN_BUF_STAT_QUEUED() + "," + 
					"C" + SEN_BUF_STAT_CANCELLED() + "," + 
					"S" + SEN_BUF_STAT_SELECT() + "," + 
					"SD" + SEN_BUF_STAT_SELECT_DONE() + "," + 
					"M" + SEN_BUF_STAT_MAPPED() + "," + 
					"FD" + SEN_BUF_STAT_FIRSTDMA() + "," + 
					"R" + SEN_BUF_STAT_REMOVED() + "," + 
					"E" + SEN_BUF_STAT_ERROR() + "," + 
					"BE" + SEN_BUF_STAT_BURST_ERROR() + "," + 
					"SE" + SEN_BUF_STAT_SIZE_ERROR() + "," + 
					"TE" + SEN_BUF_STAT_TIMEOUT_ERROR() + "," + 
					"]";
		}
	 
	 	
	
	 	public Map<String, Object> toMap(String prefix) {
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put(prefix + "/status", status);
			map.put(prefix + "/counter", counter);	
			map.put(prefix + "/isize", isize);	
			map.put(prefix + "/rsize", rsize);	
			map.put(prefix + "/map_com", map_com);
			//map.put(prefix + "/offset", offset);
			map.put(prefix + "/allocsize", allocsize);
			/*map.put(prefix + "/pagenum", pagenum);
			map.put(prefix + "/pagesize", pagesize);
			map.put(prefix + "/pagesize_last", pagesize_last);
			map.put(prefix + "/picevent", picevent);*/			
			return map;
		}
	 	
	 	@Override
	 	public Object clone() {
	 		DEVBUF copy = new DEVBUF();
	 		copy.status = this.status;
	 		copy.counter = this.counter;
	 		copy.isize = this.isize;
			copy.rsize = this.rsize;
			copy.map_com = this.map_com;
			copy.offset = this.offset;
			copy.allocsize = this.allocsize;
			copy.pagenum = this.pagenum;
			copy.pagesize = this.pagesize;
			copy.pagesize_last = this.pagesize_last;
			copy.picevent = this.picevent;
			copy.pagetab = this.pagetab;
			copy.transfertab = this.transfertab;
			copy.ptrtransfer = this.ptrtransfer;
			copy.pci_dev = this.pci_dev;
			return copy;
		}
	};

	//defines for struct DEVBUF
	public static final String  SEN_BUF_STATUS     = "pcc:c0";
	public static final String  SEN_BUF_DATA       = "pcc:c1";
	public static final String  SEN_BUF_DEVSTAT    = "pcc:c2";
	public static final String  SEN_BUF_ORION      = "pcc:c3";
	public static final String  SEN_BUF_DMA_ADD    = "pcc:c4";  //parameter size,offset
	public static final String  SEN_BUF_DMA_REMOVE = "pcc:c5";
	public static final String  SEN_BUF_BUFSIZE    = "pcc:c6";  //parameter size
	public static final String  SEN_BUF_PAGESIZE   = "pcc:c7";  //parameter size
	public static final String  SEN_BUF_CLEARSFLAG = "pcc:c8";  //parameter size
	public static final String  SEN_BUF_CLEARWFLAG = "pcc:c9";  //parameter size
}
