void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nrhs != 3)
    mexErrMsgTxt("Three input arguments required.");
  if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");
  
  if (!mxIsChar(prhs[1]) ||  mxIsEmpty(prhs[1]))
    mexErrMsgTxt("The event's label must be a non-empty string.");
   
  if ((mxGetClassID(prhs[2]) != mxDOUBLE_CLASS) || mxIsEmpty(prhs[2]) || mxIsComplex(prhs[2]) || (mxGetNumberOfElements(prhs[2]) != 1))
    mexErrMsgTxt("The id must be set by a single double value representing an integer.");

  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  btk::EventCollection::Pointer events = acq->GetEvents();
  
  size_t strlen_ = (mxGetM(prhs[1]) * mxGetN(prhs[1]) * sizeof(mxChar)) + 1;
  char* l = (char*)mxMalloc(strlen_);
  mxGetString(prhs[1], l, strlen_);
  std::string label = std::string(l);
  
  int id = static_cast<int>(mxGetScalar(prhs[2]));
  
  for (btk::EventCollection::Iterator it = events->Begin() ; it != events->End() ; ++it)
  {
    if ((*it)->GetLabel().compare(label) == 0)
      (*it)->SetId(id);
  }
  
  mxFree(l);
  
  btkMXCreateEventsStructure(acq, nlhs, plhs);
};
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nrhs != 3)
    mexErrMsgTxt("Three input arguments required.");
  if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");
  
  if ((mxGetClassID(prhs[1]) != mxDOUBLE_CLASS) || mxIsEmpty(prhs[1]) || mxIsComplex(prhs[1]) || (mxGetNumberOfElements(prhs[1]) != 1))
    mexErrMsgTxt("The index of the event must be set by a single double value representing an integer.");
  
  if (!mxIsChar(prhs[2]) || mxIsEmpty(prhs[2]))
    mexErrMsgTxt("Event's label must be a non-empty string.");    

  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  
  int idx = static_cast<int>(mxGetScalar(prhs[1])) - 1;
  if ((idx < 0) || (idx >= acq->GetEventNumber()))
    mexErrMsgTxt("Event's index out of range.");
  btk::Event::Pointer evt = acq->GetEvent(idx);
  
  size_t strlen_ = (mxGetM(prhs[2]) * mxGetN(prhs[2]) * sizeof(mxChar)) + 1;
  char* newLabel = (char*)mxMalloc(strlen_);
  mxGetString(prhs[2], newLabel, strlen_);
  evt->SetLabel(newLabel);
  mxFree(newLabel);
  
  btkMXCreateEventsStructure(acq, nlhs, plhs);
};
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nrhs != 3)
    mexErrMsgTxt("Three input arguments required.");
  if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");
  
  if (!mxIsChar(prhs[1]) ||  mxIsEmpty(prhs[1]))
    mexErrMsgTxt("The event's label must be a non-empty string.");
   
  if (!mxIsChar(prhs[2]))
    mexErrMsgTxt("The description must be set by a string.");

  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  btk::EventCollection::Pointer events = acq->GetEvents();
  
  size_t strlen_ = (mxGetM(prhs[1]) * mxGetN(prhs[1]) * sizeof(mxChar)) + 1;
  char* l = (char*)mxMalloc(strlen_);
  mxGetString(prhs[1], l, strlen_);
  std::string label = std::string(l);
  
  strlen_ = (mxGetM(prhs[2]) * mxGetN(prhs[2]) * sizeof(mxChar)) + 1;
  char* d = (char*)mxMalloc(strlen_);
  mxGetString(prhs[2], d, strlen_);
  std::string desc = std::string(d);
  
  for (btk::EventCollection::Iterator it = events->Begin() ; it != events->End() ; ++it)
  {
    if ((*it)->GetLabel().compare(label) == 0)
      (*it)->SetDescription(desc);
  }
  
  mxFree(l);
  mxFree(d);
  
  btkMXCreateEventsStructure(acq, nlhs, plhs);
};
// btkAppendEvent(h, label, time, context)
// btkAppendEvent(h, label, time, context, subject)
// btkAppendEvent(h, label, time, context, subject, description)
// btkAppendEvent(h, label, time, context, subject, description, id)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nrhs < 4)
    mexErrMsgTxt("Minimum of four inputs required.");
  if (nlhs > 2)
    mexErrMsgTxt("Too many output arguments.");
  
  btk::Event::Pointer evt = btk::Event::New();
  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  btk::Acquisition::EventConstIterator it;
  
  // Label
  if (!mxIsChar(prhs[1]) || mxIsEmpty(prhs[1]))
    mexErrMsgTxt("The label must be a non-empty string.");
  else
  {
    size_t strlen_ = (mxGetM(prhs[1]) * mxGetN(prhs[1]) * sizeof(mxChar)) + 1;
    char* buffer = (char*)mxMalloc(strlen_);
    mxGetString(prhs[1], buffer, strlen_);
    evt->SetLabel(buffer);
    mxFree(buffer);
    it = acq->FindEvent(evt->GetLabel());
  }
  // Time
  if ((mxGetClassID(prhs[2]) != mxDOUBLE_CLASS) || mxIsEmpty(prhs[2]) || mxIsComplex(prhs[2]) || (mxGetNumberOfElements(prhs[2]) != 1))
    mexErrMsgTxt("The time must be set by a numerical (double) value.");
  else
  {
    double t = mxGetScalar(prhs[2]);
    evt->SetTime(t);
  }
  // Context
  if (!mxIsChar(prhs[3]))
    mexErrMsgTxt("The context must be a string.");
  else
  {
    size_t strlen_ = (mxGetM(prhs[3]) * mxGetN(prhs[3]) * sizeof(mxChar)) + 1;
    char* buffer = (char*)mxMalloc(strlen_);
    mxGetString(prhs[3], buffer, strlen_);
    evt->SetContext(buffer);
    mxFree(buffer);
  }
  // Subject (optional)
  if (nrhs >= 5) 
  {
    if (!mxIsChar(prhs[4]))
      mexErrMsgTxt("The subject must be a string.");
    else
    {
      size_t strlen_ = (mxGetM(prhs[4]) * mxGetN(prhs[4]) * sizeof(mxChar)) + 1;
      char* buffer = (char*)mxMalloc(strlen_);
      mxGetString(prhs[4], buffer, strlen_);
      evt->SetSubject(buffer);
      mxFree(buffer);
    }
  }
  else // Use the first name in the SUBJECTS:NAMES parameter.
  {
    btk::MetaData::ConstIterator subjects = acq->GetMetaData()->FindChild("SUBJECTS");
    if (subjects != acq->GetMetaData()->End())
    {
      btk::MetaData::ConstIterator names = (*subjects)->FindChild("NAMES");
      if (names != (*subjects)->End())
      {
        if ((*names)->GetInfo() != btk::MetaDataInfo::Null)
        {
          if ((*names)->GetInfo()->GetDimensionsProduct(1) != 0)
          {
            evt->SetSubject(btkTrimString((*names)->GetInfo()->ToString(0)));
          }
        }
      }
    } 
  }
  // Description (optional)
  if (nrhs >= 6)
  {
    if (!mxIsChar(prhs[5]))
      mexErrMsgTxt("The description must be a string.");
    else
    {
      size_t strlen_ = (mxGetM(prhs[5]) * mxGetN(prhs[5]) * sizeof(mxChar)) + 1;
      char* buffer = (char*)mxMalloc(strlen_);
      mxGetString(prhs[5], buffer, strlen_);
      evt->SetDescription(buffer);
      mxFree(buffer);
    }
  }
  else // Use the description of the first event with the same label.
  {
    if (it != acq->EndEvent())
      evt->SetDescription((*it)->GetDescription());
  }
  // ID (optional)
  // If the function was called from btkEmulateC3Dserver, the ID was set to a fake
  // value (-65536) used later to store correctly some events in the C3D header section
  if (nrhs >= 7)
  {
    if ((mxGetClassID(prhs[6]) != mxDOUBLE_CLASS) || mxIsEmpty(prhs[6]) || mxIsComplex(prhs[6]) || (mxGetNumberOfElements(prhs[6]) != 1))
      mexErrMsgTxt("The ID must be set by a single double representing an integer value.");
    else
    {
      int id = static_cast<int>(mxGetScalar(prhs[6]));
      if (id == -65536)
      {
        evt->SetDetectionFlags(0x10000);
        id = 0;
      }
      evt->SetId(id);
    }
  }
  else // Use the ID of the first event with the same label.
  {
    if (it != acq->EndEvent())
      evt->SetId((*it)->GetId());
  }
  
  acq->AppendEvent(evt);
  
  btkMXCreateEventsStructure(acq, nlhs, plhs);
};