#include "Packages.h"

/*costruttore di default*/
TelepatiPkg::TelepatiPkg(){
  static unsigned short serialCreator = 0 ; /* Numero seriale del pacchetto. */
  aibo=ADDR_INVALID;
  size=0;
  message=0;
  needAck=false;
  serialNum=serialCreator++;
}


/* Imposta i valori dell'header di default dei TelepatiPkg. L'Header aggiunto o i dati partono dall'Offset puntato da STD_HEADER_SIZE di ptr*/
TelepatiPkg::TelepatiPkg(byte* ptr){
  type=(pkg_type)ptr[0];
  aibo=(int)ptr[1];
  memcpy(&size, (ptr+2), sizeof(unsigned short));
  needAck=(ptr[4] == 0?false:true);
  memcpy(&serialNum, (ptr+5), sizeof(unsigned short));
  message=0;
}


/*  crea l'header standard del pacchetto.*/
byte* TelepatiPkg::createStdHeader(size_t pkgDataSize){
  size=pkgDataSize+STD_HEADER_SIZE;
  byte* ptr=new byte[size];
  ptr[0]=(byte)type;
  ptr[1]=(byte)aibo;
  memcpy((ptr+2), &size, sizeof(unsigned short));
  ptr[4]=(byte)(needAck?1:0);
  memcpy((ptr+5), &serialNum, sizeof(unsigned short));
  return ptr;
}


size_t TelepatiPkg::getSizeOfPkg(byte* ptr){
  unsigned short size;
  memcpy(&size, (ptr+2), sizeof(unsigned short));
  return (size_t)size;
}

/*PATTERN Simple Factory. costruisce un TelepatiPkg. A partire da un array di byte ricostrusce l'oggetto corretto richiamando il costruttore corretto e lo ritorna. @param byte[] array di byte rappresentanti l'oggetto @return TelepatiPkg* oggetto di tipo TelepatiPkg* corretto*/
TelepatiPkg* TelepatiPkg::createPkg(byte* ptr){
  pkg_type type=(pkg_type)ptr[0];
  
  switch(type){
  case DUMMY:
    return new DummyPkg(ptr);
    break;
    
  case INFO:
    return new AiboInfoPkg(ptr);
    break;
    
  case HI:
    return new HiPkg(ptr);
    break;
    
  case HIREPLY:
    return new HiReplyPkg(ptr);
    break;
    
  case COUNTER:
    return new CounterPkg(ptr);
    break;
    
  case BYE:
    return new ByePkg(ptr);
    break;
    
  case ACK:
    return new AckPkg(ptr);
    break;

  case DUMMYLED:
    return new DummyLedPkg(ptr);
    break;

  case TIMEINFO:
    return new TimeInfoPkg(ptr);
    break;

  case LEADER:
    return new LeaderPkg(ptr);
    break;

  case COMMAND:
    return new CommandPkg(ptr);
    break;

  case LEADERREPLY:
    return new LeaderReplyPkg(ptr);
    break;

  case OTHHEADREADY:
    return new OthHeadReadyPkg(ptr);
    break;  

  case OTHLEGSREADY:
    return new OthLegsReadyPkg(ptr);
    break;

  case BREAKTHELINE:
    return new BreakTheLinePkg(ptr);
    break;

  default:
    return 0;
  }
}  //createPkg() END
