// PyEPL: hardware/eeg/scalp/epleeg.cpp
//
// Copyright (C) 2003-2005 Michael J. Kahana
// Authors: Ian Schleifer, Per Sederberg, Aaron Geller, Josh Jacobs
// URL: http://memory.psych.upenn.edu/programming/pyepl
//
// Distributed under the terms of the GNU Lesser General Public License
// (LGPL). See the license.txt that came with this file.

#include "epleeg.h"


EEG::EEG()
{
  // not attached
  share = NULL;
}

EEG::~EEG()
{
  // Stop recording if recording
  RecStop();

  // Detach
  ShmDetach();
  
}

int EEG::Attached()
{
  return (share != NULL);
}

int EEG::ShmAttach()
{

  void *shared_memory = (void *) 0;
  int shm_id;
  
  
  if (share == NULL)
  {
    // attach to the KERNEL module's shared memory
    rt_shm = (struct SharedMem *) mbuff_attach(SHARED_MEM_NAME, sizeof(struct SharedMem));
    
    if (!rt_shm || rt_shm->magic != SHARED_MEM_MAGIC ) {
      //fprintf(stderr, "Cannot attach to shared memory.. "
      //      "load rt_broker_module.o!\n");
      rt_shm=NULL;
      return ERROR_MBUFF_ATTACH;
    }
    
    // attach to BROKER's shared memory
    shm_id = shmget((key_t)SHARE_KEY, sizeof(struct shared_use_st), 0666);
    
    // Checking shared memory
    if(shm_id == -1) 
    { 
      //cerr << "SHMGET: Did not attach to EEG shared memory.\n";
      
      share = NULL;
      return ERROR_SHMEM_ATTACH;
    }
    
    // Make broker's shared memory accessible by program
    shared_memory = (struct shared_use_st*)shmat(shm_id,(void *)0, 0);
    if(shared_memory == (void *)-1) 
    {
      //cerr << "SHMAT: Did not attach to EEG shared memory.\n";
      share = NULL;
      return ERROR_SHMEM_ACCESS;
    }
    
    // Make pointer to the broker's share memory 
    share = (struct shared_use_st *)shared_memory;
    
    if (share->magic !=SHARED_MEM_MAGIC){
      //cerr << "Shared memory does not have the right magic key. Check that the header versions are all in sync\n";
      share = NULL;
      return ERROR_SHMEM_MAGIC;
    }
  }

  return 0;
}

int EEG::ShmDetach()
{
  // Clean shared memory if needed
  if (share != NULL)
  {
    if (shmdt(share) == -1) 
    { 
      //cerr << "Failed to detach from shared memory.\n"; 
      return -1;
    }
    share=NULL;
  }
  
  return 0;
}


int EEG::RecStart(char *filename)
{
  // make sure that we are attached
  if (share == NULL)
  {
    return -1;
  }

  // we are attached, so go for it!
  // set the filename
  strncpy(share->file_name,filename,FILE_NAME_SIZE);

  // set the record state
  share->file_state = FILE_REC_START;  

  start_rec_time = rt_shm->scan_index;

  // sleep for a tiny bit to allow for recording to start
  //usleep(1000*500);

  return 0;
}


int EEG::RecStop()
{
  // make sure that we are attached
  if (share == NULL)
  {
    return -1;
  }

  // we are attached, set the record state
  share->file_state = FILE_REC_STOP;

  return 0;
}


long EEG::GetOffset()
{
  // make sure that we are attached
  if (share == NULL)
  {
    return 0;
  }

  // return the offset into the eeg file
  return rt_shm->scan_index - start_rec_time + 1;
}

