#ifndef TIRESTORAGE_H
#define TIRESTORAGE_H

/*


Tire structure for saving the des turple (s1,s2,s3,s4)
*/
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <set>
#include <deque>
#include "Des.h"
#include "DesState.h"

#define TRIESEGSIZE 100000 //segment size for trie, used in found list.

//new add for Nonblocking
#define STATE_SEG 1000000 //store int for each state attachment
#define STATE_LIST_ATTACHMENT 10 // each state contain 10 state blog
#define STATE_LIST_ATTACHMENT_SEG 1000000// the stateblog for each state



using namespace std;


namespace DESpot
{


//---not change required------
class LinkedList{
public:
  LinkedList()
 {
  node=NULL;
  next=NULL;
}
  ~LinkedList()
  {
  }
  void addNode(int * innode) 
 {
  node=innode;
}
  int * getNode()
  {
  return node;
}
  void setNext(LinkedList * inNext)
{
  next=inNext;
}
  LinkedList * getNext()
{
  return next;
}

private:
  int * node;
  LinkedList * next;
};



//------------need change the State type define
template<typename T>
class TrieNode{

public:
  TrieNode()
{
  next = null;
}
  ~TrieNode()
{
}
bool hasChildren() {
  return next != null;
}
  TrieNode * getNode(int index)
{
  return next+index;
}
  void addNode(TrieNode * node)
{
  next=node;
}
    
void setState(T * state)//-------need change
{
  next = (TrieNode*)state;
}

T * getState() const
{
  return (T*)next;
}

private:
  // NOTE: not type safe, ideally this should be, but it may take up more
  // memory in order to make it type safe
  TrieNode<T> * next;
};


////////////////////-----------Controblility algo////////////////////////////
class AlgoTrie{
public:
	 typedef std::vector<const Des*> DesSet;
	 typedef std::vector<short> SrcStateTuple;
private:
  int blocknumber;
  int id;
  TrieNode<DesState> *root;
  long index;
  TrieNode<DesState> * pin;  
  LinkedList * nodeSegList;


  DesSet &dictDES;
  short numDES;       //need outside define
public:
	AlgoTrie(DesSet &inDESSet):dictDES(inDESSet),numDES(dictDES.size())
  {
  blocknumber=0;
  index=0;
  pin=NULL;
  nodeSegList=NULL;
  root= allocateNode(1);
  id=0;
  }
  
  ~AlgoTrie() 
  {
  LinkedList * temp;
  temp=nodeSegList;
  while(nodeSegList){
    pin=(TrieNode<DesState>*)(nodeSegList->getNode());
      delete [] pin;
    nodeSegList=nodeSegList->getNext();
  }
  delete temp;
  }
  
int insert(SrcStateTuple *sl)
{
  
  TrieNode<DesState> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
     node->addNode(allocateNode(((int)dictDES[nDES]->getLastUsedStateId().id())+1));   //--------------dictDES[nDES] need to be define
    }
   node=node->getNode((*sl)[nDES]);
  }
  if(!node->getState())
  {
    // TODO: Why is something that is very evidently not a DesState* being cast
    // to a DesState*?
    // Originally, this function accepted a void pointer, so any pointer could
    // have been passed. What was this pointer intended to convey?
    // Was it just so that getState wouldn't be null?
	  node->setState((DesState*)node); // need to be change
	  id++;
    return id-1;
  }else
  {
    return id-1; //state exists
  }

}




bool search(SrcStateTuple *sl)
{
   TrieNode<DesState> *node=root;
 for(short nDES=0;nDES<numDES;nDES++)
 {
    if(!node->hasChildren())
	{
		return false;
    }
     node=node->getNode((*sl)[nDES]);
  }
  if((!node->getState()))
  {
	  return false;
  }
  else
  {
	   return true;
  }
}

  
 
  //use a linkedlist to manage the memory block usage----Memory Block----(understand)
  TrieNode<DesState> * allocateNode(int size)
  {
  TrieNode<DesState> * ttn; 
  if((index+size>= TRIESEGSIZE)||(!index)){//used up old seg, allocate new and set the link
	  ++blocknumber;
    LinkedList * temp=new LinkedList;	
    pin = new TrieNode<DesState>[TRIESEGSIZE];
    temp->setNext(nodeSegList);
    temp->addNode((int*)pin);//may change
    nodeSegList=temp;
    ttn=pin;
    pin=pin+size;
    
    index=size;
    return ttn;
  }
  ttn=pin;
  pin=pin+size;
  index+=size;
  return ttn;
}
  


int  getStateCount()
{
	return id;
}
  
int getBlockNumber()
{
	return blocknumber;
}
};


/////////////////////////////-----MeetSyn Algo----------------------------//////////////////////



class MeetSynTrie{

public:
	 typedef std::vector<const Des*> DesSet;
	 typedef std::vector<short> SrcStateTuple;
	 typedef std::vector<int*> TheArrayList;
public:
  TheArrayList m_array;
  int blocknumber;
  int id;
  TrieNode<int> *root;
  long index;
  TrieNode<int> * pin;  
  LinkedList * nodeSegList;
  DesSet &dictDES;
  short numDES;       //need outside define
  int m_size;

public:
  MeetSynTrie(DesSet &inDESSet):dictDES(inDESSet),numDES(dictDES.size()),m_size(100000)
  {

	  
  blocknumber=0;
  index=0;
  pin=NULL;
  nodeSegList=NULL;
  root= allocateNode(1);
  id=1;
  }
  
  ~MeetSynTrie() 
  {
  LinkedList * temp;
  temp=nodeSegList;
  while(nodeSegList){
    pin=(TrieNode<int>*)(nodeSegList->getNode());
      delete [] pin;
    nodeSegList=nodeSegList->getNext();
  }
  delete temp;
  }
  

void insert(SrcStateTuple *sl) ///changed---still need change 
 {
  TrieNode<int> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
      node->addNode(allocateNode(((int)dictDES[nDES]->getLastUsedStateId().id())+1)); 
    }
    node=node->getNode((*sl)[nDES]);
  }
  if(!node->getState())
  { 
	  int* state=setID(id);
      node->setState(state); 
	  id++;
  }
}


bool search(SrcStateTuple *sl)
{
   TrieNode<int> *node=root;
 for(short nDES=0;nDES<numDES;nDES++)
 {
    if(!node->hasChildren())
	{
		return false;
    }
     node=node->getNode((*sl)[nDES]);
  }
  if((!node->getState()))
  {
	  return false;
  }
  else
  {
	   return true;
  }
}

  TrieNode<int> * allocateNode(int size)
  {
  TrieNode<int> * ttn;
  if((index+size>= TRIESEGSIZE)||(!index)){//used up old seg, allocate new and set the link
	  ++blocknumber;
    LinkedList * temp=new LinkedList;
    pin = new TrieNode<int>[TRIESEGSIZE];
    temp->setNext(nodeSegList);
    temp->addNode((int*)pin);//may change
    nodeSegList=temp;
    ttn=pin;
    pin=pin+size;
    
    index=size;
    return ttn;
  }
  ttn=pin;
  pin=pin+size;
  index+=size;
  return ttn;
}
 
int* setID(int id)
{

	
 int arraylist_id=(id-1)%m_size;
 int item_id=(id-1)/m_size;
 if(item_id==0)
 {
	int* temp=new int[m_size];
	m_array.push_back(temp);
 }
 int* m_temp=m_array[arraylist_id];
  *(m_temp+item_id)=id;
  return (m_temp+item_id);
}
  

int getStateId(SrcStateTuple *sl)
{
   TrieNode<int> *node=root;
 for(short nDES=0;nDES<numDES;nDES++)
 {
     node=node->getNode((*sl)[nDES]);
  }

 return *(node->getState());

}



};


























//-----------Nonblocking-------------------------------


class State
{
public:
State()
{
	counter=0;
	pin=NULL;
	temp=NULL;
}
~State()
{
	if(temp!=NULL)
	{
		free(temp);
	}
}

void initialize(int *start_address,int m_id)
{
	pin=start_address;
	id=m_id;
}

void setValue(int in_value)
{

    if(counter<STATE_LIST_ATTACHMENT)
	{
		pin[counter]=in_value;
	}
	else
	{
		if(counter%STATE_LIST_ATTACHMENT==0)
		{
			int blocknumber=counter/STATE_LIST_ATTACHMENT;
			temp=(int*)realloc(temp,blocknumber*STATE_LIST_ATTACHMENT*sizeof(int));
		}
		temp[counter-STATE_LIST_ATTACHMENT]=in_value;
	}
	counter++;
}

int getValue(int in_index)
{
	if(in_index<STATE_LIST_ATTACHMENT)
	{
		return *(pin+in_index);
	}
	else
	{
		return *(temp+in_index-STATE_LIST_ATTACHMENT);
	}
}

short returnUpperBound()
{
	return counter-1;
}
public:
int id;
private:
int *temp;
int *pin;
short counter;
};




class NonblockTrie
{
public:
	 typedef std::vector<const Des*> DesSet;
	 typedef std::vector<short> SrcStateTuple;
	 typedef std::deque<int> MarkedStateQue;
public:
  MarkedStateQue m_queue;
private:
  //original trie structure
  int blocknumber;
  int id;
  TrieNode<State> *root;
  long index;
  TrieNode<State> * pin;  
  LinkedList * nodeSegList;

  //for state info
  int aStateIndex;
  State *pinState;
  LinkedList* listhead;
  LinkedList* listback;
  //for state attachment int list info
  int alistIndex;
  int *pinList;
  LinkedList* statelisthead;
  LinkedList* statelistback;



 // DictDES *dictDES; // need outside define
  //--changed
  DesSet &dictDES;
  short numDES;       //need outside define
public:
	NonblockTrie(DesSet &inDESSet):dictDES(inDESSet),numDES(dictDES.size())
	{
		//original trie structure
		blocknumber=0;
        index=0;
        pin=NULL;
        nodeSegList=NULL;
        root= allocateNode(1);
        id=0;
       //for state info
        aStateIndex=0;
        listhead=NULL;
        listback=NULL;
       //for state attachment int list info
		alistIndex=0;
        statelisthead=NULL;
        statelistback=NULL;
	}
  ~NonblockTrie() 
  {
	  //original trie structure
	  destoryMemory();
     //need to delete
	  destoryAllStateList();
      destoryAllState();
  }

////////////////////////////////////////////////////--change one
void insert(SrcStateTuple *sl) ///changed------------------------for initial state enter
 {
  bool isMarked = true;
  TrieNode<State> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
      // Need enough memory to store up until the last id used
      // The last id may be a larger number than the number of states,
      // but this id is what is used to access the next node in the trie
      node->addNode(allocateNode(((int)dictDES[nDES]->getLastUsedStateId())+1));  
    }
    node=node->getNode((*sl)[nDES]);
    isMarked&=dictDES[nDES]->getState((*sl)[nDES]).isMarked();
  }
  if(!node->getState())
  { 
	State* state=createState();
	state->initialize(createStateList(),id);
	if(isMarked==true)
	{
		pushPending(id);//-----------------------------------------------------------need to define
	}
    node->setState(state); 
	id++;
  }
}


void insert(SrcStateTuple *sl,int m_id, bool useEvent) ///changed---still need change 
 {
  bool isMarked = true;
  TrieNode<State> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
      // Need enough memory to store up until the last id used
      // The last id may be a larger number than the number of states,
      // but this id is what is used to access the next node in the trie
      node->addNode(allocateNode(((int)dictDES[nDES]->getLastUsedStateId())+1));  
    }
    node=node->getNode((*sl)[nDES]);
	isMarked&=dictDES[nDES]->getState((*sl)[nDES]).isMarked();
  }
  if(!node->getState())
  { 
	State* state=createState();
	state->initialize(createStateList(),id);
	if(isMarked==true)
	{
		pushPending(id);//-----------------------------------------------------------need to define
	}
	if(useEvent==true)
	{
		state->setValue(m_id);
	}
    node->setState(state); 
	id++;
  }
}


int getStateId(SrcStateTuple *sl) const
{
  TrieNode<State> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
      throw EX("find id error");
    }
    node=node->getNode((*sl)[nDES]);
  }

  if((!node->getState()))
  {
	  throw EX("find id error");
	  return 0;
  }
  else
  {
	  return (node->getState())->id;
  }
}

bool search(SrcStateTuple *sl,int m_id,bool useEvent) const
{
   TrieNode<State> *node=root;
 for(short nDES=0;nDES<numDES;nDES++)
 {
    if(!node->hasChildren())
	{
		return false;
    }
     node=node->getNode((*sl)[nDES]);
  }
  if((!node->getState()))
  {
	 // throw EX("search error");
	  return false;
  }
  else
  {
	  State* state=node->getState();
	  if(useEvent==true)
	  {
		  state->setValue(m_id);
	  }
	   return true;
  }
}



void pushPending(int id)
{
	m_queue.push_back(id);
}




///////////////////////////////////////////////////

//----------------------------------Memory allocation-------------------------------------------//
private:
  TrieNode<State> * allocateNode(int size)
  {
  TrieNode<State> * ttn;
  if((index+size>= TRIESEGSIZE)||(!index)){//used up old seg, allocate new and set the link
	  ++blocknumber;
    LinkedList * temp=new LinkedList;
    pin = new TrieNode<State>[TRIESEGSIZE];
    temp->setNext(nodeSegList);
    temp->addNode((int*)pin);//may change
    nodeSegList=temp;
    ttn=pin;
    pin=pin+size;
    
    index=size;
    return ttn;
  }
  ttn=pin;
  pin=pin+size;
  index+=size;
  return ttn;
}

public:
void destoryMemory()
{
	if(nodeSegList!=NULL)
	{
		TrieNode<State>* m_pin=NULL;
	    LinkedList* curMTemp=nodeSegList;
		while(curMTemp!=NULL)
		{
			LinkedList* nxtMTemp=curMTemp->getNext();
            m_pin=(TrieNode<State>*)(curMTemp->getNode());
		    delete [] m_pin;
		    delete curMTemp;
		    curMTemp=nxtMTemp;
		}
		nodeSegList=NULL;

	}
}

//---------------------------create ,access and delete the State---------------------------//NEW ADD NEED TEST
private:
State* createState()
{  
	if(!(aStateIndex%STATE_SEG))
	{
		LinkedList *newlist=new LinkedList;
		pinState=new State[STATE_SEG];
		aStateIndex=1;
		if(listhead==NULL)
		{
			listhead=newlist;
			listback=newlist;
            
		}
		else
		{
            listback->setNext(newlist);
            listback=newlist;
		}
		listback->addNode((int*)pinState);
        return pinState;
	}
	return &pinState[aStateIndex++];
}
public:
void destoryAllState()
{
	if(listhead!=NULL)
	{
		State* m_pinstate=NULL;
        LinkedList* curTemp=listhead;
		while(curTemp!=NULL)
		{
			LinkedList* nxtTemp=curTemp->getNext();
            m_pinstate=(State*)curTemp->getNode();
            delete []m_pinstate;
	        delete curTemp;
            curTemp=nxtTemp;
		}
		listhead=NULL;
	}

}
public:
State* getState(int index) const
{
  int statelist_id=index/STATE_SEG;
  int pinloc_id=index%STATE_SEG;
  LinkedList* temp=listhead;
  
  if(statelist_id==0)
  {
    State *m_pin=(State*)(temp->getNode());
    return &m_pin[pinloc_id];
  }
  for(int i=1;i<=statelist_id;i++)
  {
    temp=temp->getNext();
  }
  State *m_pin=(State*)(temp->getNode());
  return &m_pin[pinloc_id];
}
//--------------------Create delete the statelist--------------------------------------------------//NEW ADD AND NEED TEST

private:
int* createStateList()
{
  if(!(alistIndex%STATE_LIST_ATTACHMENT_SEG))
  {
  LinkedList *newlist=new LinkedList;
   pinList=new int[STATE_LIST_ATTACHMENT_SEG];
   alistIndex=STATE_LIST_ATTACHMENT;//10
   if(statelisthead==NULL)
   {   
       statelistback=newlist;
       statelisthead=newlist;
       statelistback->setNext(NULL);
   }
   else
   {
      statelistback->setNext(newlist);
      statelistback=newlist;
      statelistback->addNode((int*)pinList);
   }
    return pinList;
  
  }
    int* temp=&pinList[alistIndex];
    alistIndex+=STATE_LIST_ATTACHMENT;
    return temp;
}
public:
void destoryAllStateList()
{
	if(statelisthead!=NULL)
	{
		int * m_pinstatelist=NULL;
        LinkedList* curListTemp=statelisthead;
        while(curListTemp!=NULL)
		{
			LinkedList* nxtListTemp=curListTemp->getNext();
            m_pinstatelist=(int*)curListTemp->getNode();
            delete []m_pinstatelist;
	        delete curListTemp;
            curListTemp=nxtListTemp;
		}
		statelisthead=NULL;
	}
}
//----------------------------
public:

int getStateCount() const
{
	return id;
}
  
int getBlockNumber() const
{
	return blocknumber;
	
}

};



//----------------------PN6 ALGO-------------------------------------






class IntPN6Trie
{
public:
	 typedef std::vector<const Des*> DesSet;
	 typedef std::vector<short> SrcStateTuple;
	 typedef std::deque<int> MarkedStateQue;
	 typedef std::set<int> SemiMarkedStateSet;
public:
  MarkedStateQue m_queue;
  SemiMarkedStateSet semi_set;
private:
  //original trie structure
  int blocknumber;
  int id;
  TrieNode<State> *root;
  long index;
  TrieNode<State> * pin;  
  LinkedList * nodeSegList;

  //for state info
  int aStateIndex;
  State *pinState;
  LinkedList* listhead;
  LinkedList* listback;
  //for state attachment int list info
  int alistIndex;
  int *pinList;
  LinkedList* statelisthead;
  LinkedList* statelistback;



 // DictDES *dictDES; // need outside define
  //--changed
  DesSet &dictDES;
  short numDES;       //need outside define
public:
	IntPN6Trie(DesSet &inDESSet):dictDES(inDESSet),numDES(dictDES.size())
	{
		//original trie structure
		blocknumber=0;
        index=0;
        pin=NULL;
        nodeSegList=NULL;
        root= allocateNode(1);
        id=0;
       //for state info
        aStateIndex=0;
        listhead=NULL;
        listback=NULL;
       //for state attachment int list info
		alistIndex=0;
        statelisthead=NULL;
        statelistback=NULL;
	}
  ~IntPN6Trie() 
  {
	  //original trie structure
	  destoryMemory();
     //need to delete
	  destoryAllStateList();
      destoryAllState();
  }

////////////////////////////////////////////////////--change one
void insert(SrcStateTuple *sl,int int_pos) ///changed------------------------for initial state enter
 {
  bool isMarked = true;
  bool isSemiMarked=true;
  TrieNode<State> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
      node->addNode(allocateNode(((int)dictDES[nDES]->getLastUsedStateId())+1));  
    }
    node=node->getNode((*sl)[nDES]);
    isMarked&=dictDES[nDES]->getState((*sl)[nDES]).isMarked();
	if(nDES<=int_pos)
	{
		isSemiMarked&=dictDES[nDES]->getState((*sl)[nDES]).isMarked();
	}
  }
  if(!node->getState())
  { 
	State* state=createState();
	state->initialize(createStateList(),id);
	if(isMarked==true)
	{
		pushPending(id);//-----------------------------------------------------------need to define
	}
	else if(isSemiMarked==true&&isMarked!=true)
	{
		pushSemiPending(id);
	}
    node->setState(state); 
	id++;
  }
}


void insert(SrcStateTuple *sl,int m_id, bool useEvent, int int_pos) ///changed---still need change 
 {
  bool isMarked = true;
  bool isSemiMarked=true;
  TrieNode<State> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
      node->addNode(allocateNode(((int)dictDES[nDES]->getLastUsedStateId())+1));  
    }
    node=node->getNode((*sl)[nDES]);
	isMarked&=dictDES[nDES]->getState((*sl)[nDES]).isMarked();
    if(nDES<=int_pos)
	{
		isSemiMarked&=dictDES[nDES]->getState((*sl)[nDES]).isMarked();
	}

  }
  if(!node->getState())
  { 
	State* state=createState();
	state->initialize(createStateList(),id);
	if(isMarked==true)
	{
		pushPending(id);//-----------------------------------------------------------need to define
	}
	else if(isSemiMarked==true&&isMarked!=true)
	{
		pushSemiPending(id);
	}
	if(useEvent==true)
	{
		state->setValue(m_id);
	}
    node->setState(state); 
	id++;
  }
}


int getStateId(SrcStateTuple *sl)
{
  TrieNode<State> *node=root;
  for(short nDES=0;nDES<numDES;nDES++)
  {
    if(!node->hasChildren())
	{
      node->addNode(allocateNode(((int)dictDES[nDES]->getLastUsedStateId())+1));  
    }
    node=node->getNode((*sl)[nDES]);
  }

  if((!node->getState()))
  {
	  throw EX("find id error");
	  return 0;
  }
  else
  {
	  return (node->getState())->id;
  }
}

bool search(SrcStateTuple *sl,int m_id,bool useEvent)
{
   TrieNode<State> *node=root;
 for(short nDES=0;nDES<numDES;nDES++)
 {
    if(!node->hasChildren())
	{
		return false;
    }
     node=node->getNode((*sl)[nDES]);
  }
  if((!node->getState()))
  {
	 // throw EX("search error");
	  return false;
  }
  else
  {
	  if(useEvent==true)
	  {
		  node->getState()->setValue(m_id);
	  }
	   return true;
  }
}



void pushPending(int id)
{
	m_queue.push_back(id);
}

void pushSemiPending(int id)
{
   semi_set.insert(id);
}


///////////////////////////////////////////////////

//----------------------------------Memory allocation-------------------------------------------//
private:
  TrieNode<State> * allocateNode(int size)
  {
  TrieNode<State> * ttn;
  if((index+size>= TRIESEGSIZE)||(!index)){//used up old seg, allocate new and set the link
	  ++blocknumber;
    LinkedList * temp=new LinkedList;
    pin = new TrieNode<State>[TRIESEGSIZE];
    temp->setNext(nodeSegList);
    temp->addNode((int*)pin);//may change
    nodeSegList=temp;
    ttn=pin;
    pin=pin+size;
    
    index=size;
    return ttn;
  }
  ttn=pin;
  pin=pin+size;
  index+=size;
  return ttn;
}

public:
void destoryMemory()
{
	if(nodeSegList!=NULL)
	{
		TrieNode<State>* m_pin=NULL;
	    LinkedList* curMTemp=nodeSegList;
		while(curMTemp!=NULL)
		{
			LinkedList* nxtMTemp=curMTemp->getNext();
            m_pin=(TrieNode<State>*)(curMTemp->getNode());
		    delete [] m_pin;
		    delete curMTemp;
		    curMTemp=nxtMTemp;
		}
		nodeSegList=NULL;

	}
}

//---------------------------create ,access and delete the State---------------------------//NEW ADD NEED TEST
private:
State* createState()
{  
	if(!(aStateIndex%STATE_SEG))
	{
		LinkedList *newlist=new LinkedList;
		pinState=new State[STATE_SEG];
		aStateIndex=1;
		if(listhead==NULL)
		{
			listhead=newlist;
			listback=newlist;
            
		}
		else
		{
            listback->setNext(newlist);
            listback=newlist;
		}
		listback->addNode((int*)pinState);
        return pinState;
	}
	return &pinState[aStateIndex++];
}
public:
void destoryAllState()
{
	if(listhead!=NULL)
	{
		State* m_pinstate=NULL;
        LinkedList* curTemp=listhead;
		while(curTemp!=NULL)
		{
			LinkedList* nxtTemp=curTemp->getNext();
            m_pinstate=(State*)curTemp->getNode();
            delete []m_pinstate;
	        delete curTemp;
            curTemp=nxtTemp;
		}
		listhead=NULL;
	}

}
public:
State* getState(int index)
{
  int statelist_id=index/STATE_SEG;
  int pinloc_id=index%STATE_SEG;
  LinkedList* temp=listhead;
  
  if(statelist_id==0)
  {
    State *m_pin=(State*)(temp->getNode());
    return &m_pin[pinloc_id];
  }
  for(int i=1;i<=statelist_id;i++)
  {
    temp=temp->getNext();
  }
  State *m_pin=(State*)(temp->getNode());
  return &m_pin[pinloc_id];
}
//--------------------Create delete the statelist--------------------------------------------------//NEW ADD AND NEED TEST

private:
int* createStateList()
{
  if(!(alistIndex%STATE_LIST_ATTACHMENT_SEG))
  {
  LinkedList *newlist=new LinkedList;
   pinList=new int[STATE_LIST_ATTACHMENT_SEG];
   alistIndex=STATE_LIST_ATTACHMENT;//10
   if(statelisthead==NULL)
   {   
       statelistback=newlist;
       statelisthead=newlist;
       statelistback->setNext(NULL);
   }
   else
   {
      statelistback->setNext(newlist);
      statelistback=newlist;
      statelistback->addNode((int*)pinList);
   }
    return pinList;
  
  }
    int* temp=&pinList[alistIndex];
    alistIndex+=STATE_LIST_ATTACHMENT;
    return temp;
}
public:
void destoryAllStateList()
{
	if(statelisthead!=NULL)
	{
		int * m_pinstatelist=NULL;
        LinkedList* curListTemp=statelisthead;
        while(curListTemp!=NULL)
		{
			LinkedList* nxtListTemp=curListTemp->getNext();
            m_pinstatelist=(int*)curListTemp->getNode();
            delete []m_pinstatelist;
	        delete curListTemp;
            curListTemp=nxtListTemp;
		}
		statelisthead=NULL;
	}
}
//----------------------------
public:

int getStateCount()
{
	return id;
}
  
int getBlockNumber()
{
	return blocknumber;
	
}

};






















}
#endif